DDD building blocks in context of DDDSample.Net
Information about Domain Driven Design building blocks in original DDDSample can be found
. 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.
The following image shows all three aggregates present in DDDSample.NET: Cargo, Handling and Location.
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.
aggregate represents the same concept of cargo, but is dedicated to handling event registration logic.
is part of supporting subdomain which models location concepts such as
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
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).
entity is the main one. It is a container for the majority of domain logic. Cargo consists of numerous helper
, like Itinerary
. 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.
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
is a domain event
. It is a kind of entity which is, unlike normal
, immutable after creation. There is a slight difference between DDDSample and DDDSample.Net in modeling HandlingEvents. They are
in the original version, but we made them parts of a HandlingHistory
in our .NET version. More about our reasoning can be found in
Value objects are those elements of domain model that do not have their own identity, only the data. Two instances of a particular
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.
is a container for legs. It represents the route for a particular cargo. It could be implemented alternatively either as an
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
), 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
which also is not a good idea. The best approach seems to be the one implemented in DDDSample(.Net)--Itinerary as a
. It makes Cargo aggregate more granular and each of its individual objects more focused on their primary role.
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
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'.