I'm in the process of designing part of my companies architecture for its Java EE web applications. I'm pretty clear on the reasons to use a façade and one or more DAOs. The problem I have is this:
There will be some logic that definitely belongs in the integration tier because it's all about keeping the data model consistent. Except the logic goes beyond simply maintaining referential integrity and other 'raw' persistence tasks which will be handled by JPA and Hibernate. I don't class this as business logic because it's separate to any business function. However, my understanding is that a DAO should only implement the logic required to access and persist objects to the data source.
My conclusion is that I need a 'business object'-like pattern which is appropriate for the integration tier. I've looked around and the closest thing I have found (yet still not quite right to my mind) is the Sun Transfer Object Assembler pattern.
Either there's a gap in my understanding of Java EE or there is a pattern out there that will fit.
maybe a mediator is what you want:
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
then you can use a DaoMediator in order to coordinate two or more DAOs
It sounds to me like you may be missing a controller, and consequently may need the MVC pattern. The controller will look after the DAOs and present a consistent view (don't think in terms of GUIs, burt rather some client-facing interface). When modifications are made via this view, then the controller coordinates the changes to the model via the DAO. I suspect that your facade objects may be the view in this scenario.
Having said this, I wouldn't worry too much about identifying particular patterns. You often find that taking into account all your requirements and separating concerns where applicable, that you end up implementing a particular pattern and only identify it as such after the fact.
Have you considered using aggregates from Domain Driven Design?
I'm a student of DDD myself and it seems the business logic you're trying to design could be accomplished by richer POJO-like domain models. You'd have each
domain object to be responsible for its aggregate objects, and also including any logic concerning that business concept; that said, your integration layer would coordinate those rich objects but would refrain from having real logic per se (i.e several conditional logic).
Perhaps the pattern you're trying to find is actually a step into richer domain objects?
I think it's a DataMapper (or Adapter) pattern between your DAL and your Business Layer, but without a more concrete understanding i couldn't be sure.
What is driving the requirement for consistency between the DAOs? If there is some business assumption that is dictating the relationship. For example, you might have an invoice type that when it is 'Capital' then we have to make sure several other objects are in the right state or have the right set of values. This is definitely outside the realm of the data-layer.
I wouldn't try to hard to find the perfect pattern for this case. You need some sort of coordinating class though, a mediator or controller of some sort.
Related
I (think I) just understood the differences between Java Entity, VO, POJO, Javabeans, DAO, DTO, etc, I mean, the theory. Now, I'm trying to understand the implications of the implementations depending on the needs. Who cares if I create a POJO or a JavaBean? At the beginning I will create a POJO if I have no other constraint, until I realise I must make it a Javabean and deal with it's restrictions.
When do you tell yourself: "I need a DTO"? Only for web services or when any client/server call is made? In that case, do you put all the data you need (and the one you think you will need?) in one DTO bunch?
Lastly, in a MVC model, where does each one go? Can I make an entity or a vo in either layer? Where does the DTO go?
Thank you very much
You understood the difference between them, now you need to understand their purpose.
There is a neat definition for each one in this link.
Who cares if I create a POJO or a JavaBean? At the beginning I will create a POJO if I have no other constraint, until I realise I must make it a Javabean and deal with it's restrictions.
You need to think what the purpose of the class is. Is it a standalone class with no annotations that provides functionality but can be isolated (not counting libraries used)? Then it is likely a POJO.
Is it a class that serves as a bridge between layers of your project? Is it annotated? Does it implement some business logic for your project? Then it is a JavaBean.
When do you tell yourself: "I need a DTO"? Only for web services or when any client/server call is made? In that case, do you put all the data you need (and the one you think you will need?) in one DTO bunch?
DTOs are generally used to share information between layers. Their main purpose is isolating Entities so that you can change how your information is persisted from how the information flows through the different beans and controllers in your project.
To know when I need a DTO and when not I follow these rules:
Does the method more than three parameters? Then use a DTO.
Does the method return more than a single parameter? Then use a DTO.
When passing parameters to method calls / from method results: Does each element have more than one type (for Maps you would look at the value)? Then use a Collection of DTOs.
Otherwise use String, int, Long, etc.
Also never mind reusing DTOs even if most of its fields are not used for a specific method, you won't be wasting much memory if it's properly design. On the other hand, don't worry if you need to create new DTOs that share fields with some others, it might be clearer when reviewing your code. Try to find the right balance between too many DTOs and overpopulated DTOs.
Lastly, in a MVC model, where does each one go? Can I make an entity or a vo in either layer? Where does the DTO go?
It depends on how you structure your project. The term layer is a bit open as it can refer to each of the MVC elements and to the Data/Business/Client architecture (when I used the word layer in this answer, I'm talking about the later classification).
It is a good practice to separate each layer in a different project (specially in large projects). This is a common structure I use for enterprise web applications:
ProjectNameDao: Includes database access methods and entities.
ProjectNameBo: Includes all the business logic. Shares information with the other layers by using DTOs. It is, along ProjectNameDao, the Model in a MVC model.
ProjectNameWeb: Includes views and controllers from the MVC model.
ProjectNameDto: Includes all DTOs.
ProjectNameUtils: Shared utils, normally POJOs that hold constant values or provide basic functionality like Date formatting.
This structure needs to be adapted to whatever your requirements are, of course.
REST API - DTOs or not?
I would like to re-ask this question in Microservices' context. Here is the quote from original question.
I am currently creating a REST-API for a project and have been reading
article upon article about best practices. Many seem to be against
DTOs and simply just expose the domain model, while others seem to
think DTOs (or User Models or whatever you want to call it) are bad
practice. Personally, I thought that this article made a lot of sense.
However, I also understand the drawbacks of DTOs with all the extra
mapping code, domain models that might be 100% identical to their
DTO-counterpart and so on.
Now, My question
I am more aligned towards using one Object through all the layers of my application (In other words, just expose Domain Object rather than creating DTO and manually copying over each fields). And the differences in my Rest contract vs domain object can be addressed using Jackson annotations like #JsonIgnore or #JsonProperty(access = Access.WRITE_ONLY) or #JsonView etc). Or if there is one or two fields that needs a transformation which cannot be done using Jackson Annotation, then I will write custom logic to handle just that (Trust me, I haven't come across this scenario not even once in my 5+ years long journey in Rest services)
I would like to know if I am missing any real bad effects for not copying the Domain to DTO
I would vote for using DTOs and here is why:
Different requests (events) and your DB entities. Often it happens that your requests/responses different from what you have in the domain model. Especially it makes sense in microservice architecture, where you have a lot of events coming from other microservices. For instance, you have Order entity, but the event you get from another microservice is OrderItemAdded. Even if half of the events (or requests) are the same as entities it still does make sense to have a DTOs for all of them in order to avoid a mess.
Coupling between DB schema and API you expose. When using entities you basically expose how you model your DB in a particular microservice. In MySQL you probably would want to have your entities to have relations, they will be pretty massive in terms of composition. In other types of DBs, you would have flat entities without lots of inner objects. This means that if you use entities to expose your API and want to change your DB from let's say MySQL to Cassandra - you'll need to change your API as well which is obviously a bad thing to have.
Consumer Driven Contracts. Probably this is related to the previous bullet, but DTOs makes it easier to make sure that communication between microservices is not broken whilst their evolution. Because contracts and DB are not coupled this is just easier to test.
Aggregation. Sometimes you need to return more than you have in one single DB entity. In this case, your DTO will be just an aggregator.
Performance. Microservices implies a lot of data transferring over the network, which may cost you issues with performance. If clients of your microservice need less data than you store in DB - you should provide them less data. Again - just make a DTO and your network load will be decreased.
Forget about LazyInitializationException. DTOs doesn't have any lazy loading and proxying as opposed to domain entities managed by your ORM.
DTO layer is not that hard to support with right tools. Usually, there is a problem when mapping entities to DTOs and backwards - you need to set right fields manually each time you want to make a conversion. It's easy to forget about setting the mapping when adding new fields to the entity and to the DTO, but fortunately, there are a lot of tools that can do this task for you. For instance, we used to have MapStruct on our project - it can generate conversion for you automatically and in compile time.
The Pros of Just exposing Domain Objects
The less code you write, the less bugs you produce.
despite of having extensive (arguable) test cases in our code base, I have came across bugs due to missed/wrong copying of fields from domain to DTO or viceversa.
Maintainability - Less boiler plate code.
If I have to add a new attribute, I don't have to add in Domain, DTO, Mapper and the testcases, of course. Don't tell me that this can be achieved using a reflection beanCopy utils, it defeats the whole purpose.
Lombok, Groovy, Kotlin I know, but it will save me only getter setter headache.
DRY
Performance
I know this falls under the category of "premature performance optimization is the root of all evil". But still this will save some CPU cycles for not having to create (and later garbage collect) one more Object (at the very least) per request
Cons
DTOs will give you more flexibility in the long run
If only I ever need that flexibility. At least, whatever I came across so far are CRUD operations over http which I can manage using couple of #JsonIgnores. Or if there is one or two fields that needs a transformation which cannot be done using Jackson Annotation, As I said earlier, I can write custom logic to handle just that.
Domain Objects getting bloated with Annotations.
This is a valid concern. If I use JPA or MyBatis as my persistent framework, domain object might have those annotations, then there will be Jackson annotations too. In my case, this is not much applicable though, I am using Spring boot and I can get away by using application-wide properties like mybatis.configuration.map-underscore-to-camel-case: true , spring.jackson.property-naming-strategy: SNAKE_CASE
Short story, at least in my case, cons doesn't outweigh the pros, so it doesn't make any sense to repeat myself by having a new POJO as DTO. Less code, less chances of bugs. So, going ahead with exposing the Domain object and not having a separate "view" object.
Disclaimer: This may or may not be applicable in your use case. This observation is per my usecase (basically a CRUD api having 15ish endpoints)
The decision is a much simpler one in case you use CQRS because:
for the write side you use Commands that are already DTOs; Aggregates - the rich behavior objects in your domain layer - are not exposed/queried so there is no problem there.
for the read side, because you use a thin layer, the objects fetched from the persistence should be already DTOs. There should be no mapping problem because you can have a readmodel for every use case. In worst case you can use something like GraphQL to select only the fields you need.
If you do not split the read from write then the decision is harder because there are tradeoffs in both solutions.
I am going through Domain Driven Design(DDD) techniques and I am feeling like I didn't understand it well yet.
DDD suggests putting the business logic(not infrastructure stuff like persistence, security etc) in Domain Objects, Repositories for Persistence, Aggregators for assembling Domain Objects for Client(Presentation), Services which are thin layer on top of the Domain objects and Repositories, Aggregators and acts as Transactional boundary.
Let me put it in this way:
In DDD, ViewController --> SomeService --> {Domain Objects, Repositories, Aggregators}
In my current (Procedural style) approach:
ViewController --> SomeService --> DAO/Repository
Here ViewController talks to one or more Services to pull/push the data from/to the database using DAOs. If any business logic which only operates on properties of a Domain object will be in a method in that Domain Object itself. And finally the data got from service(s) are aggregated into DTOs to be presented in View Layer.
So to me both approaches almost looks similar.
Can someone explain me what I am missing?
P.S: I am adding some more info to better explain my question.
In theory everyone is saying DDD suggests "Logic should be in Domain Objects". OK.
Let us take a real scenario.
In ShoppingCart application, some user placed an Order. To process the Order I need to do all the following sub-tasks:
Get Each Item details and calculate the total Order Price.
Get the Delivery Address and Validate it using some Address Verification Service
Validate/Authenticate CreditCard Details
Save all the Order related info into DB
So by following DDD I will put the logic,
Order Total calculation in Order object which loops through its List objects.
In Address Object i would have validate() method which invokes some BING address validation.
In CreditCard class I would have authorize() method which calls some CCAuthorizationService to authorize using some third party services.
Save all order stuff into DB using some Repositories.
All these steps will be triggered by calling Order.process()
If this is correct DDD approach? If it is, our Domain Objects directly interacting with Repositories which seems to be violation of separation of concerns.
If this is not correct DDD approach, can some one please tell me how do you design for the above usecase?
DDD is language independent, it's about understanding the domain through experts and building a common language with which you can talk about the domain. So it cannot be compared directly to functional, procedural or object oriented programming languages, as they're not comparable.
View Controllers are specific to MVC frameworks and aren't specific to DDD.
In MVC a DTO for preparing data for the view would be a View Model.
Hope some of this helps.
It boils down to where the logic lives. In DDD logic primarily goes into the model layer so it stays near the data. In procedural code, logic goes into transactional layers so it is separated from the data. Fowler has a good description you can read about here.
They are similar.
Hopefully you're actually comparing "OOP" with "DDD". DDD is a subset of OOP (IMO), or at least should be in an OOPL. DDD is a specific way of thinking about breaking up responsibilities.
It's not about the technology or OOP or anything like that.
It's about focusing on the domain at hand, the language used by domain experts, understanding the domain and modelling that domain so that important concepts are present in the code.
It was originally done using OOP and many claimed that it could only be done using OOP.
However, lately people like Greg Young have shown how to do DDD in functional languages and still keep the focus on the domain.
Procedural code tend to ignore all that and just focus on how to read/write data from whatever datasource there is. e.g. integrating with a system like Movex there will be a billion tables and columns with completely retarded names like TAXEM.YAROOD FOOB.AAR which makes no sense to anyone reading that code...
It is common in Java applications to have :
an IHM layer
a service layer
a dao layer
It is common that each layer has it's own objects and relies on converters to transform objects from a layer to the other.
In my case, I use Sing MVC as the IHM layer, and MyBatis as the doa layer.
Since Spring MVC and MyBatis use only beans without any annotations on that beans :
Is it necessary to have differents objects on the 3 layers ?
Is it a good practice to share the same object between the 3 layers ?
Or why it is not recommended to do so ?
In most cases it is a good practice to keep a full seperation between layers.
Lets say you have an object called UserDAO that holds user data, and after writing quite a lot of code on all layers you decide to update sureName to be lastName in the object, now you have to go through all the layers and change every reference to that object field.
On the other hand, if you kept this object on the DB layer and mapped it to other objects on the upper layers, all you need to change is the mapping:
somObj.setUserLastName(dao.getSureName());
to:
somObj.setUserLastName(dao.getLastName());
of course this is a silly example, but it is just for demonstration.
On the other hand, seperating every object on every layer might cause a lot of redundency and duplication and can turn into a maintenance horror, so you need to think of the pros and cons and decide where it is most suitable to seperate and where not.
I have worked on both projects that have a model for each layer and projects that have a good domain model.
My preference goes to a domain model where the developers and architects took the time to develop it and think about the use of each field.
This kind of domain model is much easier to maintain and update.
I remember having to add a field to the DAO layer which implied I had to update 3 models and 4 converters. The risk of introducing bugs is major. Especially if each layer has, for example, another implementation of the Date object. (Dao --> java.sql.Timestamp, Service --> java.util.Date).
So I advise a good domain model shared across all layers.
I used to design my application around anemic domain model, so I had many repository object, which were injected to the big, fat, transaction-aware service layer. This pattern is called Transaction script. It's not considered a good practice since it leads to the procedural code, so I wanted to move forward to the domain driven design.
After reading couple of articles on the web, listening to the Chris Richardson's talk on Parleys and reading DDD chapters of the POJOs in Action, I think I got the big picture.
Problem is, that I don't know, how to organize transactions in my application. Chis Richardson in his book states:
The presentation tier handles HTTP requests from the user’s browser by calling
the domain model either directly or indirectly via a façade, which as I
described in the previous chapter is either a POJO or an EJB.
Good so far, but Srini Penchikala on InfoQ article states:
Some developers prefer managing the transactions in the DAO classes which is a poor design. This results in too fine-grained transaction control which doesn't give the flexibility of managing the use cases where the transactions span multiple domain objects. Service classes should handle transactions; this way even if the transaction spans multiple domain objects, the service class can manage the transaction since in most of the use cases the Service class handles the control flow.
Ok, so if I understand this correctly, repository classes should not be transactional, service layer (which is now much thinner) is transactional (as it used to be in Transaction script pattern). But what if domain objects are called by presentation layer directly? Does it mean, that my domain object should have transactional behavior? And how to implement it in Spring or EJB environment?
This seems kind of weird to me, so I'd be happy if somebody would clarify that. Thank you.
My personal take on applying DDD with Spring and Hibernate, so far, is to have a stateless transactional service layer and access the domain objects through that. So the way I'm doing it the domain model does not know about transactions at all, that is handled entirely by the services.
There is an example application you might find helpful to take a look at. It looks like Eric Evans was involved in creating it.
See this extremely useful blog-post. It explains how to achieve smooth DDD while not loosing Spring's and JPA's capabilities. It is centered around the #Configurable annotation.
My opinion on these matters is a bit non-popular. Anemic data model is actually not wrong. Instead of having one object with data+operations, you have two objects - one with data and one with operations. You can view them as one object - i.e. satisfying DDD, but for the sake of easier use they are physically separated. Logically they are the same.
Yes, this breaks encapsulation, but it doesn't make you use some 'magic' (aop + java agent) in order to achieve your goals.
As for the transactions - there is something called Transaction propagation. Spring supports it with #Transactional(propagation=Propagation.REQUIRED).
See this, point 9.5.7. In case you want your transactions to span multiple methods (of multiple objects) you can change the propagation attribute accordingly.
You can also use #Transactional in your service layer, where appropriate, but this might introduce a lot of boilerplace service-classes in cases when you want to use simple, single-step operations like "save".
I think one easy way to get started with DDD and Spring and have good examples of how to deal with transactions is by looking at one of the sample apps that get shipped with Spring Roo. Roo churns out code that follows the DDD principles. It relies heavily on AspectJ. I suspect it was implemented building on the ideas put forward (back in 2006) by one of SpringSource's heavyweights, Ramnivas Laddad, in this talk.
Unnfortunately I haven't make myself familiar with Spring but I will give feedback about your DDD understanding. Reading your description of transaction it is obvious that you haven't understand DDD especially Aggregate, Aggregate Root, and Repository concept.
In DDD transaction can't span across aggregates so one Aggregate will always have one transaction.