POCO in Domain Driven Design(DDD) - domain-driven-design

The POCO class has behaviors in domain driven design such as Validate() method, Is it true?

Yes - the "Entity" encapsulates the data and the behaviour of the object - so it isn't a plain old contract object any longer, it is a domain object.
One way to think of it is to imagine that none of your other code could see the properties of the object, so they can't do...
if (myDomainObject.Name != null) ...
They have to call
if (myDomainObject.IsValid()) ...
When you change the rules about what makes it valid, the change only needs to be done in the domain object as you have stopped the logic from leaking outside into the code that uses it.

Yes, the classes of the Domain Model in Domain-Driven Design should focus on behavior, if that is what you mean.

No. They do not have methods like Validate().
A DDD entity should always be in a valid state. That's why we use behaviors (methods) on the classes and not public property setters.
Does this approach cause POCO have dependency?
No. Typically everything depends on the DDD model and not vice versa.

Related

Does AutoMapper pattern violate principle of DDD?

I am trying Abp framework recently and happily found that it is a wonderful implementation of DDD. But since it uses AutoMapper to translate DTOs into Entities/Aggregates, I have noticed it's able to short-circuit my private setters of Aggregates, which obviously violated the main rule of DDD. Although the goal of AutoMapper is to reduce manual operations, but DDD emphasizes invariant through private setters.
How can I make there two seemingly conflicting concept clear and use this framework smoothly? Does that mean I have to give up AutoMapper to keep DDD principles or vice versa?
I believe AutoMapper is not an anti-pattern of DDD since it's very popular in the community. In another word, if AutoMapper can use reflection (as I know) to set private setters, anybody else can. Does that means private setters is essentially unsafe?
Thanks for anyone could help me or have me a hint.
AutoMapper is: A convention-based object-object mapper in .NET.
In itself, AutoMapper does not violate the principle of DDD. It is how you use it that possibly does.
How can I make there two seemingly conflicting concept clear and use this framework smoothly? Does that mean I have to give up AutoMapper to keep DDD principles or vice versa?
No, you don't have to give up AutoMapper.
You can specify .IgnoreAllPropertiesWithAnInaccessibleSetter for each map.
Related: How to configure AutoMapper to globally Ignore all Properties With Inaccessible Setter(private or protected)?
In another word, if AutoMapper can use reflection (as I know) to set private setters, anybody else can. Does that means private setters is essentially unsafe?
No, that means that reflection is very powerful.
Don't know a lot about the Abp framework. Private setters is just good old traditional OOP which is used in DDD (encapsulation). You should expose public methods from your aggregate that will change its state. Automapper can be used in your application layer where you map the DTOs to domain building blocks (like value objects) and you pass them as parameters in your aggregate public functions that will change its own state and enforce invariants. Having said that not everyone loves Automapper :)
How can I make there two seemingly conflicting concept clear and use this framework smoothly?
By configuring AutoMapper's profile to construct the aggregate root using a custom expression that uses the aggregate's factory methods or constructors. Here is an example from one of my projects:
public class BphNomenclatureManagerApplicationAutoMapperProfile : Profile
{
public BphNomenclatureManagerApplicationAutoMapperProfile()
{
CreateMap<BphCompany, BphCompanyDto>(MemberList.Destination);
CreateMap<CreateUpdateBphCompanyDto, BphCompany>(MemberList.Destination)
// invariants preserved by use of AR constructor:
.ConstructUsing(dto => new BphCompany(
dto.Id,
dto.BphId,
dto.Name,
dto.VatIdNumber,
dto.TradeRegisterNumber,
dto.IsProducer
));
}
}

Valid domain model while using Automapper

I am using Jimmy Bogard's lovely Automapper to map my API model to the POCO classes (domain model).
The API model does not contain certain attributes of the domain model which are necessary for the domain model to be in valid state. In this scenario, when Automapper finishes its job, I have a fully constructed domain model in an invalid state.
Not using Automapper is not an option because there are too many attributes to hand code.
So, here is my question:
How do I use automapper to create the object in this manner while leaving the domain model in a valid state.
Thanks
This is probably too long for a comment:
Although Jimmy's answer is correct it may imply that your design may not be as encapsulated as it could be since you are going to have to expose a lot of state. This may be why there are comments around "anemic" models and "not fit for purpose".
If you are focused on behaviour then you may have something, totally hypothetical, as follows to make your customer a Gold customer:
customer.MakeGold();
However, using state you would now have to expose attributes that allow you to map to a Gold status. Internally your customer may have checked certain other state to determine the validity of the Gold status whereas that validity check has now moved out of the domain in the way Jimmy says he makes sure that the state is correct before passing it to the domain.
This is not so much an auto-mapper issue as it is a design issue. It also seems to indicate that your API/Integration model may be more data-centric.
On the other hand, if you are mapping to, say, command-style value objects that are handed to the domain it may not be as bad as that :)
// map my APIActivationDetails to Activate --- however automapper does this :)
var activate = AutoMapper.Map<Activate>().From(apiActivationDetails);
customer.Activate(activate);
Come to think of it... this seems to be what Jimmy is saying :P
"to map my API model to the POCO classes (domain model)"
Why would you ever want to map command object (your API model) attributes to domain objects? If that's what you are aiming for you will mostly end up with over-engineered CRUD, but certainly not a DDD solution.
Behaviors should be explicitly declared on aggregates and aggregates are responsible for mutating their own internal state according to the business invariants they protect.
That way, domain model clients can clearly state their intention and this intention isin't lost through the business process.
You shouldn't try to shove data into aggregates, instead you should ask them to perform a task.
I validate the API model before it gets mapped into my domain model, whether I'm using AutoMapper or not. The API model represents a command or action, so I'm validating the command before I apply it to my entity, not mutate my entity and then try to validate it afterwards. This also means all my validation attributes are on my API model.

In DDD, should any class that is not an Entity or an Value Object be a Service?

In DDD, should any class that is not an Entity or an Value Object be a Service?
For example, in libraries some classes are named FileReader (which read a File object), Cache interface that is implemented by MemcachedCache or FileCache, XXXManager, ...
I understand outside of DDD, you can name your classes however you want to.
But in DDD (and with the same examples), should I name my classes like FileReadingService, CacheService implemented by FileCacheService, XXXService, etc ?
I think this is really something which is only relevant to your projects naming standards. DDD does not dictate that level of detail.
My only advice would be to make sure something like FileReader is clearly segregated away from you domain. Possibly inside you infrastructure library,
There are additional types of objects in DDD, albeit in a more supporting role than Entity, Service, or ValueObject. Things like Repositories and Factories spring to mind. But in general, 'real' objects such as physical objects, or nouns in a problem description, should fall into one of those categories.
Well, i will say YES on that. even though there are other kinds of objects you might encounter but those probably will turn out to be VALUE objects after all. i think of it like this: if it is not an object that needs storing or an object that is managed by an Aggregate root then it must a service managing them.

Can a "rich domain model" violate the Single Responsibility Principle?

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.

domain driven design isDirty, isNew

If I'm strictly following DDD, aren't the concepts of IsDirty and IsNew as properties on an entity breaking the rule that the entity is supposed to deal only with it's own logic. IsDirty/IsNew are things used for persistence. Even still, I've seen people put this directly in an entity or entity base class. Isn't this a no no? What are some other approaches to getting the same functionality and moving it outside of the entity. Something like an object state tracker? I'm trying to accomplish this so I can do something like order.AddLine() and then call orderRepository.Save(order). I'd like to do this without adding logic in every single setter to say it's dirty.
You are correct that implementing isNew and isDirty is not a practice acceptable in strict adherence to DDD. Typically you want to use Unit of Work pattern to handle keeping track of the domain layer changes that need to be communicated to the persistence store.

Resources