for example, I have a Media entity, and it has MediaType value object, which responsible for holding/creating media type. What is the best place to store a list of possible media type constants? First what I can think it's to store inside of the MediaType as it's responsible for creating type. But what if I need it in the application layer, or in the interface layer to validate the request, or even in the query.
Looks like if I want to isolate domain, I can't store constants in the MediaType as I can't use it outside of the domain. Or to use the constant only in the domain layer, and hardcode it everywhere else, seems incorrect for me as in such a case we do not have a single place to change it. The third option is to create separate constants class like MediaConstantsand to store it outside of the domain (not sure where), but in such a case looks like we do not need MediaType VO at all.
What are the best practices of dealing with constants in the DDD?
Isolating your domain is, of course, what you are after. This means that your domain contains all the relevant invariants and, as you have done, enumerations and the like that you need to make your domain model expressive.
Sometimes the "outside" world is going to require duplication of sorts to make things easier and more convenient. For instance, the fact that your domain check that an e-mail address is in the correct format does not mean that your web front-end does not also perform that validation. You could forego such an e-mail validation on the front-end but that is going to end up leaving the users with a rather poor experience. We "duplicate" the validation on the front-end as a convenience.
The same goes for some data. A generic approach for flat classification structures may be something like ReferenceType 1-* ReferenceItem where ReferenceType.Name is something like MediaType and ReferenceItem.Name is whatever values you require. Sometimes you could have a Code and IsSystemType for your reference items but that is the general idea. Each reference type would have one or more reference items so a rather simple one-to-many relationship that can be easily persisted to some data store. You could then expose the values to your front-end via a query mechanism and in your integration layer/concern (web controller / message handler) you could take the relevant item name (or code) and map that to, say, your enumeration.
Related
I'm new to DDD and I want to clearly understand each domain object structure and role:
Aggregate Root:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Sorry for the long questions, but I'm feeling little lost despite of continues reading, if you can help me I would be glad.
I'll try to answer all your questions:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
Entities live within ARs and allowing the client to create them would violate encapsulation, so for entities you are correct, ARs create their own entities which don't get exposed to the outside (copies/immutable views could be).
On the other hand, value objects are generally immutable and therefore there's no harm in having them supplied to the AR as data inputs.
In general all modifications needs to go through the AR so that the AR is aware of the modification. In special situations the AR could detect modifications within it's cluster by listening to events raised by internal entities when it's impractical to go through the root.
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Favor value objects as much as you can. It's not unusual for all parts of an AR being modeled as values. However, there's no limitation or law stating whether or not an AR should have only values or entities, use the composition that's fit to your use case.
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Same answer as above, no limitation nor law.
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Primitive obsession is worst than value object obsession in my experience. The cost of wrapping a value is quite low in general, so when in doubt I'd model an explicit type. This could save you a lot of refactoring down the road.
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Static factory methods on ARs are quite common as a mean to be more expressive and follow the UL more closely. For instance, I just modeled as use case today where we had to "start a group audit". Implemented a GroupAudit.start static factory method.
Factory methods on ARs for other ARs are also quite common, such as var post = forum.post(author, content) for instance, where Post is a seperate AR than Forum.
When the process requires some complex collaborators then you may consider a standalone factory though since you may not want clients to know how to provide and setup those collaborators.
I'm new to DDD and I want to clearly understand each domain object structure and role
Your best starting point is "the blue book" (Evans, 2003).
For this question, the two important chapters to review are chapter 5 ("A model expressed in software") and chapter 6 ("the life cycle of a domain object").
ENTITIES and VALUE OBJECTS are two patterns described in chapter 5, which is to say that they are patterns that commonly arise when we are modeling a domain. The TL;DR version: ENTITIES are used to represent relationships in the domain that change over time. VALUE OBJECTS are domain specific data structures.
AGGREGATES and FACTORIES are patterns described in chapter 6, which is to say that they are patterns that commonly arise when we are trying to manage the life cycle of the domain object. It's common that modifications to domain entities may be distributed across multiple sessions, so we need to think about how we store information in the past and reload that information in the future.
The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root?
Gray area. "Creation patterns are weird." The theory is that you always copy information into the domain model via an aggregate root. But when the aggregate root you need doesn't exist yet, then what? There are a number of different patterns that people use here to create the new root entity from nothing.
That said - we don't expect the application to be directly coupled to the internal design of the aggregate. This is standard "best practice" OO, with the application code coupled to the model's interface without being coupled to the model's implementation/data structure.
Can an aggregate root contain only value objects ?
The definition of the root entity in the aggregate may include references to other entities in the same aggregate. Evans explicitly refers to "entities other than the root"; in order to share information with an entity other than the root, there must be some way to traverse references from the root to these non-root entities.
Shall the entities contain only value objects?
The definition of an entity may include references to other entities (including the root entity) in the same aggregate.
shall I go ahead and encapsulate every primitive type in an value object?
"It depends" - in a language like java, value objects are an affordance that make it easy for the compiler to give you early feed back about certain kinds of mistakes.
This is especially true if you have validation concerns. We'd like to validate (or parse) information once, rather than repeating the same check every where (duplication), and having validated vs unvalidated data be detectably different reduces the risk that unvalidated data leaks into code paths where it is not handled correctly.
Having a value object also reduces the number of places that need to change if you decide the underlying data structure needs improvement, and the value object gives you an easily guessed place to put functions/methods relating to that value.
Factories: Do I really need them?
Yes, and...
I can go ahead and write an static method within the domain object
... that's fine. Basic idea: if creating a domain object from so sufficient set of information is complicated, we want that complexity in one place, which can be invoked where we need it. That doesn't necessarily mean we need a NOUN. A function is fine.
And, of course, if your domain objects are not complicated, then "just" use the objects constructor/initializer.
I am confused about how to treat strictly UI-related things, that won't be used in the business logic in the domain model: how to properly store them in the database?
If for example I have an aggregate which is an entity and the main purpose of this model is to do something with an important thing, should I include a title in the model even though it does not contribute to the business logic in any way? Does it matter if I want to store the title in the same table I store other data for my entity (e.g. important things)?
#Entity
MyAggregate:
id: ID
title: str
importantThing: ImportantThing
def doSomethingWithImportantThing():
...
And if I don't include a title in the model, then how to properly store it using Repository pattern? If I keep the title within my model my Repository could look like so:
#Repository
MyAggregateRepository:
def create(myAggregate: MyAggregate):
...
What would happen to repository if I remove title from the model? Should it transform like so:
#Repository
MyAggregateRepository:
def create(myAggregate: MyAggregate, title: str):
...
The rule of thumb is to keep only things that are necessary for making decisions and protecting invariants inside the aggregate state. Otherwise, aggregates get polluted by alien concerns and convert to a messy one-to-one representation of an over-growing database table or document.
As any rule, it has exceptions. I don't think it's a good idea going overboard from the start and splitting the entity prematurely.
However, if you feel that things get messy and you can see patterns that a group of fields are used in a group of functions, while another group of fields is solely used in a different set of functions, you might get an idea that your aggregate deserves splitting.
The repository pattern is largely relevant for executing commands. Its main purpose is to handle the aggregate persistence. When implementing queries, consider using CQRS and write queries that you need to write, it doesn't have to be the repository that handles queries. Queries are also idempotent and have no side effect (except the performance), so it is rather safe not to think about the domain model as such when writing queries. It's better to name your queries using the Ubiquitous Language though.
Things that are purely UI-related typically don't belong in the domain unless the domain is related to managing UI-related items, such as in the case of a localisation domain.
Data that belongs in the domain would stay in the domain. For instance, if there is a comment on an AccountTransaction, or some such, then that would be in the language used by the users of the system and not something that one could localize. However, if that transaction has a Type indicator that is either Debit or Credit then you wouldn't want to necessarily use a string representation but rather codify that; even if the "code" is Debit and Credit or Dr/Cr. However, the front-end would use some l10n or i18n mechanism to display the text for the Type in the relevant language.
Hopefully I understood your question correctly.
Keep title within the bounds of your model. There are a few reasons for this.
The utility of title is kept within the bounds of the model itself, since it does not serve any other purpose in the domain layer. It serves as "identity" that is merely local to the model itself, and then gets surfaced in the UI.
The title is not necessary for creating the aggregate, since it has no business logic intent. If it did, it would represent a tighter coupling between the model and the creation of the aggregate, which is typically undesirable.
title seems to be an aggregate invariant that you'd only want the aggregate root to be concerned with, and not a concern from a perspective of external access or creation.
Ultimately, this keeps your design cleaner.
So I have few doubts regarding calling something as domain object (and eventually placing the class under domain package) or not.
I have a micro-service whose responsibility is to do some calculations (without getting into actual business requirements, all it does is calculate some return of intereset based on given request). Now to achieve the calculations there are certain sub-calculations which need to take place and hence are composed in different classes respectively. But yes, these calculation do not need to be persisted in DB , and neither they have an ID (so definitely not an Entity or Aggregate). However these individual calculator classes (for the lack of terminology) do contain some complex business logic. Now, my question is, do these individual classes still qualify/classify as domain objects or should they be referred to as services ?
Feel free to ask for more clarifications around use case if need be.
Cheers !
Now, my question is, do these individual classes still qualify/classify as domain objects or should they be referred to as services
From the DDD point of view, in the Domain layer, there are the following terms that could be implemented using classes: Domain entities, Aggregate roots (a type of Domain entity), Value objects and Domain services.
Because your things don't have an Identity they cannot be Domain entities or Aggregate roots. Calculations could be done inside Value objects or Domain services. Value objects contain specific behavior related to values so most probable your calculations are implemented using Domain services.
From my experience, not every domain class must be a DDD building block, they could be just classes extracted for better maintainability, Single responsibility principle (SOLID in general) etc.
A simple test could be asking below questions -
Does your “calculator” (as you refer it) hold the calculation result as an immutable state? — if the answer is yes then it is a Value Object.
Is the “Calculator” stateless and only exposes a “calculate” behaviour which accepts a request & returns a calculation result? — if the answer is yes then it is a Service, however, the “result” returned by this service may be classified as Value Object.
I would say that your calculations can fit well either in Value Objects or Domain Services.
How to differentiate? Well, I understand Domain Services as services (well, obvious) with business logic (such as your calculations) that require some kind of external dependency you need to inject in order to get your logic work.
On the other hand, if you can name that business logic as a business concept (i.e. CustomerFee, CustomerCommission, etc) and you don't need any injected dependency to make it work I would say it's a Value Object.
For instance, imagine that you want to calculate the price of a reservation which depends on the fee you will charge to the customer (among other params):
ReservationPrice(CustomerFee customerFee, ItemPrice ItemPrice)
Now your CustomerFee is also calculated based on (say any variable) something.
This way you are modeling your calculations just with Value Objects which allows you to show in your code all the different business concepts they depend on. Also anyone looking at your code and files structure can get an idea about what you are calculating.
An interesting thread came up when I typed in this question just now. I don't think it answers my question though.
I've been working a lot with .NET MVC3, where it's desirable to have an anemic model. View models and edit models are best off as dumb data containers that you can just pass off from a controller to a view. Any kind of application flow should come from the controllers, and the views handle UI concerns. In MVC, we don't want any behavior in the model.
However we don't want any business logic in the controllers either. For larger applications its best to keep the domain code separate from and independent of the models, views, and controllers (and HTTP in general for that matter). So there is a separate project which provides, before anything else, a domain model (with entities and value objects, composed into aggregates according to DDD).
I've made a few attempts to move away from an anemic model towards a richer one in domain code, and I'm thinking of giving up. It seems to me like having entity classes which both contain data and behavior violates the SRP.
Take for example one very common scenario on the web, composing emails. Given some event, it is the domain's responsibility to compose an EmailMessage object given an EmailTemplate, EmailAddress, and custom values. The template exists as an entity with properties, and custom values are provided as input by the user. Let's also say for the sake of argument that the EmailMessage's FROM address can be provided by an external service (IConfigurationManager.DefaultFromMailAddress). Given those requirements, it seems like a rich domain model could give the EmailTemplate the responsibility of composing the EmailMessage:
public class EmailTemplate
{
public EmailMessage ComposeMessageTo(EmailAddress to,
IDictionary<string, string> customValues, IConfigurationManager config)
{
var emailMessage = new EmailMessage(); // internal constructor
// extension method
emailMessage.Body = this.BodyFormat.ApplyCustomValues(customValues);
emailMessage.From = this.From ?? config.DefaultFromMailAddress;
// bla bla bla
return emailMessage;
}
}
This was one of my attempts at rich domain model. After adding this method though, it was the EmailTemplate's responsibility to both contain the entity data properties and compose messages. It was about 15 lines long, and seemed to distract the class from what it really means to be an EmailTemplate -- which, IMO, is to just store data (subject format, body format, attachments, and optional from/reply-to addresses).
I ended up refactoring this method into a dedicated class who's sole responsibility is composing an EmailMessage given the previous arguments, and I am much happier with it. In fact, I'm starting to prefer anemic domains because it helps me keep responsibilities separate, making classes and unit tests shorter, more concise, and more focused. It seems that making entities and other data objects "devoid of behavior" can be good for separating responsibility. Or am I off track here?
The argument in favor of a rich domain model instead of an anemic model hinges on one of the value propositions of OOP, which is keeping behavior and data next to each other. The core benefit is that of encapsulation and cohesion which assists in reasoning about the code. A rich domain model can also be viewed as an instance of the information expert pattern. The value of all of these patterns however is to a great extent subjective. If it is more helpful for you to keep data and behavior separate, then so be it, though you might also consider other people that will be looking at the code. I prefer to encapsulate as much as I can. The other benefit of a richer domain model in this case would be the possibility to make certain properties private. If a property is only used by one method on the class, why make it public?
Whether a rich domain model violates SRP depends on your definition of responsibility. According to SRP, a responsibility is a reason to change, which itself calls for a definition. This definition will generally depend on the use-case at hand. You can declare that the responsibility of the template class is to be a template, with all of the implications that arise, one of which is generating a message from the template. A change in one of the template properties can affect the ComposeMessageTo method, which indicates that perhaps these are a single responsibility. Moreover, the ComposeMessageTo method is the most interesting part of the template. Clients of the template don't care how the method is implemented or what properties are present of the template class. They only want to generate a message based on the template. This also votes in favor of keeping data next to the method.
Well, it depends on how you want to look at it.
Another way is: "Can the Single Responsibility Principle violate a rich domain model?"
Both are guidelines. There is no "principle" anywhere in software design. There are, however, good designs and bad designs. Both these concepts can be used in different ways, to achieve a good design.
Let's say we have CQRS-inspired architecture, with components such as Commands, Domain Model, Domain Events, Read Model DTOs.
Of course, we can use Value Objects in our Domain Model. My question is, should they also be used in:
Commands
Events
DTOs
I haven't seen any examples where Value Objects (VO) are used in the components mentioned above. Instead, primitive types are used. Maybe it's just the simplistic examples. After all, my understanding of VOs use in DDD is that they act as a glue for the whole application.
My motivation:
Commands.
Let's say user submits a form which contains address fields. We have Address Value Object to represent this concept. When constructing command in the client, we should validate user input anyway, and when it is well-formed, we can create Address object right there and initialize Command with it. I see no need to delegate creation of Address object to command handler.
Domain Events.
Domain Model already operates in terms of Value Objects, so by publishing events with VOs instead of converting them to primitive types, we can avoid some mapping code. I'm pretty sure it's alright to use VOs in this case.
DTOs.
If our query-side DTOs can contain Value Objects, this allows for some more flexibility. E.g., if we have Money object, we can choose whether to display it in EUR or USD, no need to change Read Model.
Ok I've changed my mind. I have been trying to deal with VOs a bunch lately and after watching this http://www.infoq.com/presentations/Value-Objects-Dan-Bergh-Johnsson it clarified a couple of things for me.
Commands and Event are messages (and not objects, objects are data + behavior), in some respects much like DTOs, they communicate data about an event and they themselves encapsulate no behavior.
Value Objects are not like DTOs at all. They are a domain representation and they are, generally speaking, rich on behavior like all other domain representations.
Commands and Events communicate information into and out of the domain respectively, but they themselves do not encapsulate any behavior. From that perspective it seems wrong and a possibly a violation context boundaries to pass VOs inside of them.
To paraphrase Oren (though he was referring to nHibernate and WCF) "Don't send your domain across the wire".
http://ayende.com/Blog/archive/2009/05/14/the-stripper-pattern.aspx
If you want to communicate a value object, then I suggest passing the necessary attributes needed to re-construct the VO within them instead.
Original Text (for posterity):
If you are asking if Value Objects can be passed by the domain model to events or passed in by commands, I don't really see a huge problem with the former, though the latter may violate some of the rules of the aggregate root being the "owner" of values.
That said a value object represents concepts like for example a color. You don't have green, you are green or not. There seems to be nothing intrinsically wrong with a command telling you that you are green by passing this.
Reading the chapter from DDD on the Aggregate Root pattern explains Entities and Value Objects quite well and is worth reading over a few times.
I say it's a bad idea.
There's a reason we don't do the same with entities - to avoid coupling other parts of the system to the domain (in the wrong places). The same is true for Value Objects, the only difference between value objects and entities is lifetime and ownership - these differences do not affect how we should and should not couple to them.
Imagine that you make an event contain a VO. A change in your domain requires you to change that VO. You've now boxed yourself into a corner where your event is also forced to change, ditto for any Commands or DTO's it's a part of.
This is to be avoided.
Use DTO's and/or primitives. Map them (AutoMapper makes it a 1-line deal).
Similar to other answers, in SOA this would break encapsulation of the service as the domain is now leaking out.
According to Clean Code your DTOs are data structures (just to add another term), while value objects are objects. The difference that objects can have behavior. Mixing data structures with objects is generally a very bad idea, because it will be hard to maintain the hybrid you get.
I don't feel right to put value objects to DTOs from an architecture perspective as well. The value objects are inside of the domain model while the DTOs you mentioned are defining the interface of the model. We usually build an interface to decouple the outside world from the inside of something. So in the current case we added DTOs to decouple the outside world from the value objects (and other model related stuff). After that adding value objects to the interface is crazy.
So you haven't met this solution yet because it is an anti-pattern.
Value Objects are or at least should be immutable. Once instantiated with a value that value will never change throughout the lifetime of the object. Thus, passing VOs as data to DTOs (such as Events) should not be an issue since all you can do with them is get their value. At the most their value in a differing representation such as toString() as opposed to an original getValue() which might return an integer or whatever the value is.