DDD building blocks in context of DDDSample.Net

Information about Domain Driven Design building blocks in original DDDSample can be found here. This article is a brief description of an approach we have chosen in DDDSample.Net and highlight differences in the way DDDSample and DDDSample.Net works.

Aggregates

The following image shows all three aggregates present in DDDSample.NET: Cargo, Handling and Location.

Domain.png

Cargo contains logic responsible for manipulating Cargo objects from administrator point of view as well as logic used to calculate various parameters describing current state of cargo delivery. It's root is Cargo entity.

Handling aggregate represents the same concept of cargo, but is dedicated to handling event registration logic.

Location is part of supporting subdomain which models location concepts such as UN/LOCODE.

Entities

Entities are the stars of the domain model. They are the most valuable elements in terms of business logic contained. They usually represent the most important real life concepts - those which have its own identity.

In DDDSample entities are quite rare. In fact small entities to value objects ratio seems to differentiate mature domain models from anemic ones. There are 4 entities in the original code and only three in current (0.6) version of DDDSample.Net (we don't support Voyages).

Cargo entity is the main one. It is a container for the majority of domain logic. Cargo consists of numerous helper value objects, like Itinerary and Delivery. Cargo has a very well defined concept of identity: the TrackingId value object represents a unique number each cargo piece is assigned when booking. This tracking id is probably printed on a box, container or whatever is used to transport the cargo so it has a strong real life representation.

Location is an entity which represents a place where cargoes being are handled, for example a port. Locations also have strong identity concept--they are identified by established UN/LOCODE standard codes.

HandlingEvent is a domain event. It is a kind of entity which is, unlike normal entities, immutable after creation. There is a slight difference between DDDSample and DDDSample.Net in modeling HandlingEvents. They are aggregate roots in the original version, but we made them parts of a HandlingHistory aggregate in our .NET version. More about our reasoning can be found in domain events section.

Value Objects

Value objects are those elements of domain model that do not have their own identity, only the data. Two instances of a particular value object are the same if they contain the same data.

There is a lot of value objects in the DDDSample domain model. There are three major groups of them:
  • those which create structure of the domain model
  • those which enable model to be more granular
  • those which make model more explicit
Here are some examples. Leg is a value object which a part of domain model just because it represents real life concept of leg--a step of an itinerary. There is nothing special about it. Leg contains only data (starting and ending location and time) and two legs containing same data are totally interchangeable.

Itinerary is a container for legs. It represents the route for a particular cargo. It could be implemented alternatively either as an entity or by incorporating its role into role of Cargo entity (there would be no Itinerary object then). The first alternative would make an Itinerary modifiable (it is read-only as a value object), but would introduce a false concept of identity--there is no identity in the Itinerary in the real life. The second one would assign yet another responsibility to Cargo entity which also is not a good idea. The best approach seems to be the one implemented in DDDSample(.Net)--Itinerary as a value object. It makes Cargo aggregate more granular and each of its individual objects more focused on their primary role.

TrackingId is an identifier for a piece of cargo. It is a value object which primary role is to make a model more explicit. Yes, we could model cargo tracking id as a string, but wrapping that string into value object makes code (and remember, code is the ultimate model) more readable since at first look we know what is the business meaning of this 'string'.

Last edited Mar 8, 2010 at 4:19 PM by SzymonPobiega, version 6

Comments

No comments yet.