2

I'm exploring Cargo DDD sample.

There is BookingService which belongs to application layer. But looking at the code, it seems that all methods correspondent to Domain Logic (bookNewCargo, assignCargoToRoute, etc).

enter image description here

Why is it in Application Layer then?

What is the difference between application and domain services?

So confusing!

  • You need to re-examine the terms you're using and make sure you fully understand them. I've never heard of the terms "application layer" and "domain layer," and using terms that you don't understand to make decisions about how your code is organized is probably not the best plan. – Robert Harvey Aug 17 '17 at 15:06
  • See Eric Evans Blue book, page 70. – Teimuraz Aug 17 '17 at 15:09
  • In the section titled "Services?" – Robert Harvey Aug 17 '17 at 15:14
  • In the section titled "Layered Architecutre" – Teimuraz Aug 17 '17 at 15:15
  • 1
    Note that there's no "right" or "wrong" way to write software. There is Eric Evans' way, Martin Fowler's way, Bob Martin's way, and the way that best meets your specific requirements. – Robert Harvey Aug 17 '17 at 15:19
7

Why is it in Application Layer then?

As far as I can tell, because this is an application service -- more specifically, because the consumer of this service is the application, not the domain.

For example, take a close look at BookingService.assignCargoToRoute, if we strip away the logging and exception handling, we see

public void assignCargoToRoute(final Itinerary itinerary, final TrackingId trackingId) {
    final Cargo cargo = cargoRepository.find(trackingId);
    cargo.assignToRoute(itinerary);
    cargoRepository.store(cargo);
}

That's a classical pattern for an application to interact with the domain.

  1. Obtain a handle to an aggregate root, with a local copy of state
  2. Send a command to the aggregate root, allowing it to update the local state
  3. Commit the local state change back into the shared repository, so that the changes are visible outside of this particular thread.

BookingService.bookNewCargo is similar; but confused by the fact that (a) creation patterns are weird and (b) this particular design is a bit anemic; the domain model, specifically the Cargo aggregate root, should be doing more of the work.

If you work through the call graph, you'll notice that

So the consumer of the BookingService is the application (indirectly, the CargoAdminController); this thing isn't a domain service at all. The domain model never knows it exists.

That's not a great argument by itself. Another hint that we are dealing with an application service here is that the implementation knows about Repository, which is not a domain concept. Given that domain services are sometimes used to bridge a gap between the rest of the domain model and some application or infrastructure service, we can conclude that heuristic isn't particularly good either.

How to distinguish between application and domain services?

My advice: don't get caught up in the labels. Pay attention to cohesion. Pay attention to what other components change when you change the service. Watch your dependency graph like a hawk -- if you find your "domain" services getting polluted with application dependencies, that's a hint that you haven't quite gotten the separation of concern properly aligned.

  • 2
    Repository is a domain concept. Domain layer defines and exposes a repository and/or data access through an interface which is generally implemented in the infrastructure. – Andy Aug 17 '17 at 17:37
  • 3
    No. Cargo is a domain concept. Itinerary is a domain concept. "Repository" is not - it's a programming concept, not a part of the ubiquitous language of moving cargo. – VoiceOfUnreason Aug 17 '17 at 17:40
  • It's still the domain layer which exposes the interface. Some tasks are pretty much unsolvable without access to data layer, such as unique constraint validation. You are given access to data in your domain through the interfaces domain layer defines. And when a business rule that something has to be unique is made it belongs to a place where the rest of the business rules lives as well, the domain layer, not the application layer. – Andy Aug 17 '17 at 17:46
  • 1
    Sure: but note that aggregates, repositories, and factories are chapter 6 (Life Cycle of a Domain Object), where entities, value objects, and services are chapter 5 (A Model Expressed in Software). – VoiceOfUnreason Aug 17 '17 at 17:53
  • 2
    After some thorough thinking and re-reading several chapters, I need to admit my view on the problem was not entirely correct. I have thus removed my answer, because yours provides a far better insight. – Andy Aug 18 '17 at 6:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.