What is the difference between domain state vs ui state (ui concern)?
For example is the users selected locale an ui concern or we can argue that because our product has a localisation feature the locale property is part of domain state.
Do you explicitly separate user persisted ui fields in a different aggregates?
For example you could store a User model and have a separate model UserView with ui related preferences.
Related
DDD can only be use in event triggered? like POST,PUT,DELETE? I try to search on the internet for how many months, I can only see that they use DDD logic when the user form is submitted. But when retrieving the data (GET) there is no logic involve, they just query it and display in the U.I. Is that acceptable if I store computed total in the database or retrieve the data and compute it?
. Please enlighten me. Thank you.
If your application is designed with DDD for a specific bounded context, then it SHOULD be the only authoritative application for that context. It means it SHOULD be the only one able to update the that context's state. It means every changes to that context SHOULD go through this application domain layer.
If every change to this context is done by your application, and if you enforce all domain rules when updating your context state, then your context state CANNOT be persisted in an invalid state. In that situation, you don't need to enforce domain rules when reading the context's state, as this was already done when updating it.
In conclusion :
You MAY bypass your domain logic validation when reading/querying your application state IF you prevent other components from violating your authority over that context.
I'm learning DDD and have some troubles.
I've created rich domain model with value objects and some functions for manipulating model properties.
Currently i'm using in memory DB and my domain models are persisted as is.
All is good.
But now i want to separate domain model from DB model.
Scenario for creating (lets say "concert"):
User sends command.
Application service gets domain model
Then application service calls repository to persists that model
Repository (infrastrucure layer) translates that domain model to his DB model and write to DB
Second scenario (I want to update "concert")
User send command to update concert
Application service calls repository to get "concert" to update (first question what repository should return here, doest it need to return domain model or something else)
Now (if I have domain model) I can call method concert.sellTickets(3);
Then app service calls repository to update that concert
Does my thinking is good?
Does repository need to reconstruct DB model to Domain model and return to caller?
I hope you understand what I'm asking.
Above scenarios with some sample code:
Creating concert (application layer)
// application service
var concert = Concert.Create(); // creating rich domain model or concert
_repository.Add(concert);
Update concert (sell tickets) - application layer
var concert = _repository.Get(//by id); // this is rich domain model
concert.SellTickets(//some number); // calling "smart" method
_repository.Update(concert); // persisting to DB with new value
repository side (writing) (infrastructure layer)
var concert = Adapter.Map(domain_model); // converting rich domain model to plain class for pesisting
_db.Add(concert);
_db.SaveChanges();
repository side (reading) - infrastructure layer
var concert = _db.Find(); // read concert from db
var rich_domain_model = Adapter.Map(concert) // convert it to rich domain model
return rich_domain_model;
I know that ORM's using their mappers,
but let's say I'm using,for now, in memory DB. So i need to do some conversions.
These two use-cases you are presenting are pretty standard in the context of DDD world. Also, they reflect a valid separation between domain model (domain layer) and database model (infrastructure layer).
Application service gets domain model
What do you mean by "gets"? A command object received by user is a flat object, containing no value objects; it is not (and should not be) a domain model. It is possible to delegate command-to-domain translation to application service, however some would prefer to apply such translation inside API layer (it is a matter of taste).
User send command to update concert
There are probably more than one command that "update" a concert (e.g. assign musicians, order hall, selling tickets). This is why we should be careful when defining a single update operation in the context of DDD: sending a command with many properties not necessarily relating to each other is a symptom of an anemic model.
first question what repository should return here, does it need to return domain model or something else
A repository should translate database objects into a domain entity, and return the latter. In DDD all layers "know" the domain.
One last point:
A rich domain is more than entities with value objects and methods that manipulate properties; the richness should be expressed by "smart" methods, that is methods that perform appropriate validations to prevent the entity from entering an inconsistent state. If you want to project a domain model as is into database, there is no point for smart entities because running plain validations would be sufficient. But if your application is not purely CRUD, providing rich flows and structured as many user commands mutating business entities, that's where DDD shines.
I am building an application that will expose part of its features through RESTful services and my application packages is organized as below
Application --> This package contains the RESTfull services
Model --> Contains the domain model the aggregates, Value Objects,...
Infrastructure --> Contains the set of classes required to access the database
Mongo DB --> My DB
The application package exposes the endpoint
CastReview(UUID reviewedEntityId, string review)
The review the retrieved from the body of the request and it is mandatory.
Now my question is where the validation should occur
Should I keep the validation logic inside the aggregate and inside the application I just construct instance of the aggregate and check if the aggregate is valid
Or Should I have the validation inside the application package as well as inside the aggregate
For Aggregates, I wouldn't call it validation but invariant enforcement, since they are supposed to be always valid. You don't just modify an aggregate and then have it checked by an external validator, aggregates enforce their own invariants.
Some rules are clearly domain invariants since you have to have deep knowledge of aggregate data to enforce them, and some are definitely applicative rules (e.g. email confirmation == email). But sometimes the lines are blurred. I would definitely check at a client-side and applicative level that the review is not null or empty, and at the same time I wouldn't consider a Review Aggregate OK if it has a null review, so I would do both. But this might be domain-dependent and YMMV.
Integrity constraints (or "invariants", if you prefer that term) should be defined in the (domain/design/data) Model. Then they should be checked multiple times:
In the front-end User Interface (on input/change and on submit) for getting responsive validation.
In the back-end Application or Infrastructure before save.
And in the DBMS (before commit), if your DB is shared with other applications.
See also my article Integrity Constraints and Data Validation.
I am developing a Java EE business management application using the following technologies:
JSF
JPA
GlassFish 4
Derby 10.10.1.1
As a start, I created the following objects:
Person (JPA Entity)
Name
Address
Email
etc.
PersonManager (Stateless EJB)
createPerson
deletePerson
updatePerson
findPersonById
I then created the following xhtml pages with backing beans.
PersonCreater
PersonViewer
PersonUpdater
Using JSF and JPA, I found it easy to create the xhtml with backing bean to support creating, viewing and updating my person object.
Using the Java EE Security #RolesAllowed annotation, it was easy to limit access to the PersonManager methods to specific roles, and using the web.xml security-constraint element it was easy to limit JSF page access to specific roles.
I am now to the point where I want to add sensitive information such as social security number to my Person entity, but I only want specific roles to be able to create, read and update the sensitive information. Is there a standard way to add sensitive information to an entity and then control access?
My fundamental problem is with the PersonManager's getPersonById method. Currently, this method looks like the following:
#RolesAllowed("Reader")
public Person findPersonById(long id) {
return em.find(Person.class, id);
}
If I add the social security number property to the Person entity, the method will return the social security number with the returned Person to all users with role Reader. Of course, I want everyone to be able to read most of the data associated with my Person object, but I don't want everyone to be able to read the Person's social security number.
I could add logic to the gerPersonById method to remove sensitive information from the Person object based on the current role using the EJBContext's getCallerPrincipal and isCallerInRole methods. Is this a good way to limit access to the social security property?
I thought about putting all the sensitive information in another entity called PersonSensitive and then creating a OneToOne relationship between Person and PersonSensitive. However, this leads me back to the problem of how do I limit access to specific entity fields based on the current role. I tried using #RolesAllowed on the Person entity but this did not work.
I might be able to use some type of inheritance scheme where the sensitive data belongs to a descendant of Person and only specific roles can access the descendant's manager methods. However, this leads me to creating sets of JSF pages where each set is designated for use by a specific role. Maybe this is the best way to move forward but it seems like it will require much extra work.
Despite having studied Domain Driven Design for a long time now there are still some basics that I simply figure out.
It seems that every time I try to design a rich domain layer, I still need a lot of Domain Services or a thick Application Layer, and I end up with a bunch of near-anemic domain entities with no real logic in them, apart from "GetTotalAmount" and the like. The key issue is that entities aren't aware of external stuff, and it's bad practice to inject anything into entities.
Let me give some examples:
1. A user signs up for a service. The user is persisted in the database, a file is generated and saved (needed for the user account), and a confirmation email is sent.
The example with the confirmation email has been discussed heavily in other threads, but with no real conclusion. Some suggest putting the logic in an application service that gets an EmailService and FileService injected from the infrastructure layer. But then I would have business logic outside of the domain, right? Others suggest creating a domain service that gets the infrastructure services injected - but in that case I would need to have the interfaces of the infrastructure services inside the domain layer (IEmailService and IFileService) which doesn't look too good either (because the domain layer cannot reference the infrastructure layer). And others suggest implementing Udi Dahan's Domain Events and then having the EmailService and FileService subscribe to those events. But that seems like a very loose implementation - and what happens if the services fail? Please let me know what you think is the right solution here.
2. A song is purchased from a digital music store. The shopping cart is emptied. The purchase is persisted. The payment service is called. An email confirmation is sent.
Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction? Of course I could put everything in the MVC controller with injected services. But if I want real DDD all business logic should be in the domain. But which entity should have the "Purchase" method? Song.Purchase()? Order.Purchase()? OrderProcessor.Purchase() (domain service)? ShoppingCartService.Purchase() (application service?)
This is a case where I think it's very hard to use real business logic inside the domain entities. If it's not good practice to inject anything into the entities, how can they ever do other stuff than checking its own (and its aggregate's) state?
I hope these examples are clear enough to show the issues I'm dealing with.
Dimitry's answer points out some good things to look for. Often/easily you find yourself in your scenario, with a data shoveling from db up to GUI through different layers.
I have been inspired by Jimmy Nilsson's simple advice "Value objects, Value objects and more Value objects". Often people tend to focus to much on Nouns and model them as entity. Naturally you often having trouble in finding DDD behavior. Verbs are easier to associate with behavior. A good thing is to make these Verbs appear in your domain as Value objects.
Some guidance I use for my self when trying to develop the domain (must say that it takes time to construct a rich domain, often several refactoring iterations...) :
Minimize properties (get/set)
Use value objects as much as you can
Expose as little you can. Make you domain aggregates methods intuitive.
Don't forget that your Domain can be rich by doing Validation. It's only your domain that knows how to conduct a purchase, and what's required.
Your domain should also be responsible for validation when your entities make a transition from one state two another state (work flow validations).
I'll give you some examples:
Here is a article I wrote on my blog regarding your issue about anemic Domain http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/
I can also really recommend Jimmy Bogard's blog article about entity validations and using Validator pattern together with extension methods. It gives you the freedom to validate infrastructural things without making your domain dirty:
http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/
I use Udi's Domain Events with great success. You can also make them asynchronous if you believe your service can fail. You also wrap it in a transaction (using NServiceBus framework).
In your first example (just brainstorming now to get our minds thinking more of value objects).
Your MusicService.AddSubscriber(User newUser) application service get a call from a presenter/controller/WCF with a new User.
The service already got IUserRepository and IMusicServiceRepository injected into ctor.
The music service "Spotify" is loaded through IMusicServiceRepository
entity musicService.SignUp(MusicServiceSubscriber newSubsriber) method takes a Value object MusicServiceSubscriber.
This Value object must take User and other mandatory objects in ctor
(value objects are immutable). Here you can also place logic/behavior like handle subscriptionId's etc.
What SignUp method also does, it fires a Domain Event NewSubscriberAddedToMusicService.
It get caught by EventHandler HandleNewSubscriberAddedToMusicServiceEvent which got IFileService and IEmailService injected into it's ctor. This handler's implementation is located in Application Service layer BUT the event is controlled by Domain and MusicService.SignUp. This means the Domain is in control. Eventhandler creates file and sends email.
You can persist the user through eventhandler OR make the MusicService.AddSubscriber(...) method to this. Both will do this through IUserRepository but It's a matter of taste and perhaps how it will reflect the actual domain.
Finally... I hope you grasp something of the above... anyhow. Most important is to start adding "Verbs" methods to entitys and making the collaborate. You can also have object in your domain that are not persisted, they are only there for mediate between several domain entities and can host algorithms etc.
A user signs up for a service. The user is persisted in the
database, a file is generated and saved (needed for the user account),
and a confirmation email is sent.
You can apply Dependency Inversion Principle here. Define a domain interface like this:
void ICanSendConfirmationEmail(EmailAddress address, ...)
or
void ICanNotifyUserOfSuccessfulRegistration(EmailAddress address, ...)
Interface can be used by other domain classes. Implement this interface in infrastructure layer, using real SMTP classes. Inject this implementation on application startup. This way you stated business intent in domain code and your domain logic does not have direct reference to SMTP infrastructure. The key here is the name of the interface, it should be based on Ubiquitous Language.
A song is purchased from a digital music store. The shopping cart
is emptied. The purchase is persisted. The payment service is called.
An email confirmation is sent. Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction?
Use OOP best practices to assign responsibilities (GRASP and SOLID). Unit testing and refactoring will give you a design feedback. Orchestration itself can be part of thin Application Layer. From DDD Layered Architecture:
Application Layer: Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer
is responsible for are meaningful to the business or necessary for
interaction with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state
that reflects the progress of a task for the user or the program.
Big part of you requests are related to object oriented design and responsibility assignment, you can think of GRASP Patterns and This, you can benefit from object oriented design books, recommend the following
Applying UML and Patterns