0

I have a quite difficult problem to solve. In my model I have AR Unit, AR Stage and VO GoToPositionOrder, that implements Order interface.

It works like that:

  • I create order: order = GoToPositionOrder(Position(Point(3, 4)))
  • I give it to unit: unit.followOrder(order) (I can give various of orders to unit)
  • orders are stored in Unit and then I can store unit: unitRepository.store(unit)
  • orders that are stored in unit are followed by unit every step, until order is finished, so every time event TimeStep is sent, I call domain service unitsFollowOrders(unitRepository.all())

Now, where is the problem? Each order does some action on given unit (command pattern) when is followed : order.execute(unit). Problem is that different orders needs different additional data to do its action. In example GoToPositionOrder needs access to AR Stage so it can find the shortest path to position. But how can I give Order access to Stage?

I can't simply pass a reference there, because AR should be referenced by id, for various reasons. If it's referenced by id, then to retrieve it, VO would have access to repository, and that violates SRP (single responsibility principle).

What other options do I have?

Rafał Łużyński
  • 7,083
  • 5
  • 26
  • 38
  • It seems you're trying to encapsulate commands (as in the Command pattern) inside your aggregate roots in the form of VOs, which is weird. I would typically have an Application Service / command handler that takes care of fetching the aggregate roots from Repositories and coordinating calls to them instead of having the Command object itself do that, but that may not be what you're trying to get at. – guillaume31 Oct 16 '14 at 14:38
  • Well, it comes from my UL, that "units has orders". Of course I can make `VO Order` just to define order type and based on that type I can run application services on units. But my approach catches my app behaviour better than this way, because order behaviour stays in order, not in service. Anyway, does it mean that VO can't have reference to AR? If it can, then we have to load AR with given VOs, and for every found VO, load ARs that they needs. It seems really troublesome. – Rafał Łużyński Oct 16 '14 at 16:37
  • I just realized, that VO must be immutable, hence it mustn't have reference to mutable object, right? – Rafał Łużyński Oct 16 '14 at 17:10
  • I don't think VOs are the right kind of object to coordinate aggregate actions. It seems strange that a VO should have a reference to one, let alone multiple AR's. Do you really need to persist orders inside the `Unit` ? Shouldn't that be modelled as a sequence of commands that hit the AR ? – guillaume31 Oct 17 '14 at 07:14
  • Yes, you are right. I should extract operations on more than one aggregate, to domain services, though I sacrifice some model clarity. Orders needs to be stored in units anyway, because they must persist between requests, they are not ARs for sure, so I can't persist them alone. – Rafał Łużyński Oct 17 '14 at 08:49
  • Why would you store in a particular AR an order that will have a far more global impact (on other AR's, etc) ? – guillaume31 Oct 17 '14 at 10:39
  • It won't have impact on other ARs. It can have impact only on `Unit` AR, but to make that impact, it needs data from other ARs. `MoveToPositionOrder` is commanding unit everystep, to find the shortest path to given position, but to find that path, order needs `Stage` AR data. – Rafał Łużyński Oct 17 '14 at 12:07

1 Answers1

0

I think a Domain Service is the right place to put the pathfinding logic since that capability doesn't seem to belong in any Entity, is stateless, and needs data from multiple AR's.

It would have a FindShortestPath() method producing a GoToPositionOrder VO which is then injected into the Unit. The VO would contain no logic, only the list of steps to take for the Unit to reach its goal.

guillaume31
  • 13,738
  • 1
  • 32
  • 51