Where should I keep logic for derived fields (derived from attributes of the same model class) - in model layer or in service layer?
Example:
In the code below, age is derived from dateOfBirth (do not ask why you need to persist age when it can be derived from dateOfBirth in the model class - this is a hypothetical example). Where should I keep calculateAge() method - in PersonModel or PersonService?
import java.util.Date;
models/Person.java
#Entity
public class Person {
private Date dateOfBirth;
private String age;
}
service/PersonService.java
public interface PersonService {
}
Not sure what you mean by "where to keep it", but this usually depends if you want to treat your entity model as domain or persistence model. Lots of people don't need to distinguish between these two models(because the differences are minimal) and just put everything into the entity class. As soon as the domain logic becomes more important, people usually introduce some sort of domain model on top of the entity model, within which the entity state is encapsulated, and translation between the models happens in the service layer implementation.
This is an open ended question, so you won't get a definitive answer. This is just what I observed from other projects and how I understand this is usually done or supposed to be. Do what works best for you and always ask yourself if the abstraction brings value to your project before applying a design pattern like this.
Related
Short version
Why would we ever need factories (being injected in the application layer) in DDD if no aggregates will ever emerge out of thin air and doing so would cause at least an error in the modeling of the business ?
Long version
There is a popular DDD example which is the e-commerce application consisting of the following aggregates and entities (over simplified)
Modeled as
class Customer {
private CustomerId id;
// related business rules and processes
}
class Order{
private OrderId id;
private List<OrderLine> orderLines;
// related business rules and processes
}
class OrderLine{
private OrderLineId id;
private int quantity;
private ProductId product;
// related business rules and processes
}
class Product{}
// etc...
And it's well established that the creation of the order is done through a factory, usually like:
Order order = orderFactory.createNewOrder(customer);
However I'm arguing that this model is not very clear since I assume the original (made up) requirement is
Customers can place orders.
So doesn't it make more sense to delegate the creation of the order to the Customer aggregate and have the code more verbose ? i.e:
Order order = customer.placeOrder(...);
// Pass the data needed for the creation of the object, or even the factory service if the creation is complex
In my opinion, expanding this view would result in that the actors of the system would be aggregates most of the time and they will contain all the invoking of the use cases (which has the side-effect that the application layer being very thin as well)
Does this second approach violate DDD ? An aggregate being responsible for the creation of another aggregate doesn't feel right but produces better code that -in my opinion- matches the domain better.
Does this second approach violate DDD
No. The patterns described by Evans in the Domain Driven Design book should be understood as "useful ideas that recur" rather than "these patterns are mandatory".
And you will find support in the literature for the idea that, when we are modeling the creation of aggregates, we should be using the domain language, not factories. For example: Don't Create Aggregate Roots (Udi Dahan, 2009).
That said.... when Evans describes the FACTORY pattern in his book, he does so in the context of life cycle management, not modeling. In other words, factories are cousins to repositories and aggregates, not domain entities and value objects.
Shift the responsibility for creating instances of complex objects and AGGREGATES to a separate object, which may itself have no responsibility in the domain model but is still a part of the domain design.
In other words, we might still want to use Customer::placeOrder in our domain model, but to have that method delegate the object assembly to a dedicated factory.
Of course, object creation is not the only place that we use the factory pattern; it can also appear in object reconstitution. A common REPOSITORY pattern is to fetch information from the durable data store, and then pass that information to a FACTORY to arrange that information into the appropriate shape - aka the graph of objects that make up the AGGREGATE.
I understand the factory pattern as an example of information hiding, the factory limits the blast radius when we decide to change how a fixed set of information is assembled into an aggregate.
This is a sample code which haven't followed the single responsibility principle,
public class EmailSender
{
public void SendEmail(string customerID,
string emailNotificationType)
{
//STEP1: load customer details
//STEP2: get email content
//STEP3: send email (using SmtpClient class)
}
public string GetEmailContent(Customer customer,
string emailNotificationType)
{
// Build the email notification content
}
}
I agree, It will create the issue in case If I need to do following,
-> Changes in the way, you are loading customer details.
-> Changes to the email content because of requirement enhancements / changes.
-> If there any change in the way you are sending the email instead of using SmtpClient class or something like that.
so we need to apply Single Responsibility Principle to separate the classes. I totally agree on this principle. Say I need to create three classes like
EmailSender - which only focus on sending email
CustomerRepository - which only focus on fetching customer data
EmailContentBuilder - which parse the email content
But say If I have a Dao like CustomerDao, As of now I have all the CRUD operations related to CustomerDao in the same class like below
CustomerDao class
- add()
- update()
- get()
- getAll()
- update()
Do we need to apply SingleResponsibilityPrinciple here? If so How to apply for CustomerDao class?
Thanks,
Harry
You do not want to apply to DAO because it only do one thing.
good example
sourse
Patterns and principles are great things, but used incorrectly they can make a simple problem just as complex as not having them.
SRP shouldn't be understood in a strict manner. One object should have very few responsibilities, not "one".
Here CustomerDao is only responsible for Customer persistence, so it has only one responsibility.
Despite its name SRP is expressed as "A class should have only one reason to change". DAO is changed for the single reason: when mapping between database table and business object changes so DAO does not violate SRP.
Think of an example: business logic changes so that we need to add some more data to our object: we add fields to our business object, columns to database table and of course we need to change the mapping. We are likely to change get/add/update methods of our single DAO class then.
For clear understanding of the principle I would recommend reading the original source of SOLID principles: Robert Matin's book Agile Software Development, Principles, Patterns, and Practices.
As I work with my understanding of Domain Driven Design I find I have a rule that seems to work, though I would like to see if it is overkill and also would like to see other perspectives of the same situation.
My question is this: "When should the domain model and persistence model be contained in separate objects?"
My language of choice is Java at the moment and I am using Spring Data's repository model.
I see three main answers to my question.
Always use separate domain objects from persistence objects.
Use separate domain objects only when putting domain methods (behaviors) on persistence objects is not practical.
Use persistence objects as domain objects in all cases.
In order to ask questions about DDD I find that I have to use an example bounded context since I don't yet know enough about DDD to ask in a more abstract way.
Here is my illustrative bounded context: say I have a law codification system with the following business rules:
Each law on the books must be classified.
Each law has an identifier with two parts, a codification number prefix and a codification coassign suffix. (Example: 100-0100, 599-2030).
There are multiple legal jurisdictions that are using the law codification system and they should be able to make their own coassigns but the codification prefixes are global and must be the same across all jurisdictions to facilitate general comparability.
the codification number prefixes are grouped into broad codification categories. Codification categories have a number range, such as 100-199, 200-299, 700-799, etc.
To express this bounded context as a persistence model I have the following:
table: codification
fields: chart_code, prefix, coassign, codification_category
table: codification_chart
fields: chart_code, jurisdiction_description
table: codification_category
fields: category, low_category_number, high_category_number, description
table: global_codification
fields: prefix, coassign, codification_category
I know, I should be starting from the domain model first. I have a persistence model and a domain model
In my domain model I have three domain objects
public Codification {
private String prefix, coassign;
codificationCategory codificationCaegory; // an enum type
public Codification(...) { // set private vars }
// getters for private variables
}
public CodificationChart {
private List<Codification> chartCodifications = new ArrayList<>();
private String chartCode;
// public constructor to initialize private variables
// getters for private variables
public Codification addCodificationToChart(Codification){...}
public void removeCodificationFromChart(Codification){...}
public boolean checkCodificationInChart(Codification){...}
}
public enum CodificationCategory {
CIVIL, CRIMINAL, PROPERTY, CORPORATE, FAMILY, CONSUMER, ETHICS, BANKRUPTCY;
}
ORM Objects:
JPA Mappings of the tables mentioned earlier with the "Entity" suffix added to their table names.
They are omitted for brevity.
Each one contains getters and setters like JPA Pojos do.
If someone asks for the Persistence objects code I will post it.
The only point at which my domain objects know about the persistence model is in my factory object CodificationChartFactory, which has the repository interfaces I am using to interact with the ORM objects mentioned earlier. This factory is the only part of the domain that uses the persistence repositories, thus the only part that interacts with the persistence layer.
Is creating a separate domain model here wasteful effort?
I can see how it is possible for me to put my CodificationChart behaviors on a Persistence object. It just somehow feels wrong to put those behaviors on a persistence object who's only job is to retrieve a record from the database.
I definitely stand to be corrected.
Both approaches are correct and are a matter of taste from a design point of view. Some people don't want their domain object to have absolutely anything to do with persistence and do create an extra layer of Entity objects... some people don't think this is a major problem and are happy to go ahead and use the domain objects as the persistence objects.
Personally (and subjectively), I think that using JPA and have an extra layer of Entity objects is the wrong approach. The aim of ORMs like Hibernate is to be a bridge between Object and Relational models (I know it's in the name :). I think a way better approach, in the case one wants to keep things separated, is to use something like mybatis or plain SQL, but definitely not JPA... otherwise it's just adding complexity for the sake of complexity (JPA is not the easiest framework to learn)
I'm happy to live with the mix and annotate my domain objects. As I know it makes the persistence easier to manage... but at the same time, I feel very comfortable with Hibernate/JPA and been using it for 10 years :).
I had a very similar question 3 years ago, which I posted on programmers site - Do ORMs enable the creation of rich domain models?
I have inherited an application written in Java that uses JPA to access a database. The application uses an design pattern that I haven't come across before and I would really appricate some guidance on why this pattern is used. Like many applications, we have a front end, middleware, and back end database. The database is accessed via DAOs. Each method on the DAO loads a entity-DTO which is just a POJO with nothing but getters and setters and that entity-DTO is then passed into a entity-proper that has other methods that change the entity state. An example [class names changed to protect the inocent]
enum Gender
{
Male,
Female
}
class PersonDTO
{
private String mFirstName;
private String mLastName;
private Gender mGender;
...
String getFirstName() { return this.mFirstName; }
String setFirstName(String name) { this.mFirstName = name; }
// etc
}
class Person
{
PersonDTO mDTO;
Person(PersonDTO dto)
{
mDTO = dto;
}
String getFirstName() { return mDTO.getFirstName() }
String setFirstName(String name) { mDTO.setFirstName(name); }
// and so on
void marry( Person aNotherPerson )
{
if( this.getGender()==Gender.Female &&
aNotherPerson.getGender()==Gender.Male)
{
this.setLastName( aNotherPerson.getLastName() );
}
aNotherPerson.marry( this );
}
}
This is repeated across 30 or so entity classes, doubled to 60 with the DTOs, and I just cant get my head around why. I understand (bits) about seperation of converns and I also understand (bits) about the difference between an EAO based design to say an active record based design.
But does it really have to go this far? Should there always be at least one "DB" object that contains nothing but getters and setters that map to the DB fields?
Disclaimer: there are varying opinions on this subject and depending on your system's architecture you might not have a choice.
With that said... I've seen this pattern implemented before, not a huge fan of it, in my opinion is duplicates large amounts of code without adding any real value. It seems to be particularly popular in systems with XML APIs like SOAP where it might be difficult to map XML structure directly to your object structure. In your particular case it seems to be even worse because on top of duplicate getFirstName()/getLastName() methods, there is business logic (which belongs in the service layer) coded right into a pojo (which should be a simple data transfer object like the DTO). Why should the pojo know that only people of opposite sex can get married?
To help better understand why, can you explain where these DTOs come from? Is there a front-end submitting data to a controller which then converts it to a DTO, which is then used to populate your entity-proper with data?
It could also be that they are using this just to separate the JPA annotations from the rich domain object.
So I'm guessing that somebody didn't like having JPA annotations and the rich domain object behaviour in one class. Somebody could have also argued that the JPA annotation and the rich domain object should not be in the same layer (because the annotations mixes the concerns) so you would get this kind of separation if you won this argument.
Another place where you'd see this kind of thing happening is when you want to abstract similar annotations away from the rich domain objects (like jaxb annotations in web services for example).
So the intent might be that the DTO serves as sort of the serialization mechanism from code to the database, which is very similar to the intent mentioned here by martin fowler.
This doesn't appear to be a known pattern.
In general
it is common to maintain a separate object to represent the record in the database, referred to as domain object.
the CRUD operations on the object are part of a DAO class and other business operations would be part of a Manager class, but none of these classes store the domain object as a member variable, i.e. neither DAO nor Manager carry state. They are just processing elements working on domain objects passed in as parameters.
a DTO is used for communication between the front-end and back-end to render data from DB or to accept input from end-user
DTOs are transformed to Domain objects by Manager class, where validations and modifications are performed per business rules. Such domain objects are persisted in the DB using DAO class.
I have worked on one project where we have DTOs for the sole purpose of transferring information from front-end controller to some facade layer. Then facade layer is responsible for converting these DTOs to domain objects.
The idea behind this layering is to decouple front-end (view) from domain. Sometimes DTOs can contain multiple domain objects for aggregated view. But domain layer always presents clean, reusable, cacheable(if required) objects.
I have some experience with Django and its MVC (MTV rather...) concept. In my previous project in django, I always tried pack a lot of functions (methods) to Model class - all which could work on single entity in Model object. I know that in Java EE world, there is much more layers than 3, so how should I do it in Spring? For instance, where should I place function which sum up few properties of entity? Anyway, do models in spring are also called "model"?
Just apply good OO practices. If some behavior can be encapsulated in the Model class, then definitely put it in the Model class. For example, a Model having a salary and a bonus properties might of course have a getTotalIncome method which returns the sum of salary and bonus.
Of course, it shouldn't cross its own boudaries. If the computation of the total income necessitates the call of a service to apply some tax based on the current month and some configuration in the database, this becomes business logic and couples your model objet with the service layer, which should not be done. So the getTotalIncome method in this case should not exist anymore.
Typically, no, you dont add many functions in the model object itself. And spring is all about good design. In other words, the model should just be a container for the information representing model elements. Everything that is done to the model should be done through things like DAO. In spring my models usually look like this:
public class Car {
private int id;
private Engine engine;
private Control steeringWheel;
...
// getters and setters
}
With a DAO like:
public interface CarDao {
public void add( Car car );
public void update( int id, Car car );
...
}
It's less about layers and more about keeping data objects simple so that you can move them around your enterprise systems in whichever way you like without surprises. There's nothing about Spring itself that really cares how many methods you put in a class, but I agree with Lucas that keeping an entity class simple is better design.
Long experience has led me back to this conclusion many times. "Busy" entity objects end up being a pain sooner or later.
Ok, I would have a model object for Player, one for Game, and maybe one for State. I would have a DAO for each and, I would have a controller, perhaps called Controller that would perform all of the operations. For example:
public class Player {
private String name;
...
}
public class State {
private Map<Player, Location> locations;
private Map<Player, Health> healths;
...
}
public class Game {
private Player player1;
private Player player2;
private State state;
...
}
With a standard CRUD like DAO (possibly with additional helper methods), and a controller that implements an interface something like this:
public interface Controller {
public void move( Player player, Location location );
...
}
Java EE has changed a lot of patterns that were common in J2EE world. Although Spring is not Java EE it was designed around the same idea - to get rid of the legacy J2EE cumbersomeness. There's a good book by Adam Bien about J2EE patterns that have become anti-patterns - "Real World Java EE Patterns.
Rethinking Best Practices"
One of it chapters "Persistent Domain Object" answers exactly your question. Model your application with real objects and don’t care about the persistence at the beginning... JPA turns out to be really flexible in mapping rich domain objects into relational tables. The more complex logic you have to realize, the easier object-oriented persistence can be maintained and developed.