Using Spring MVC to develop a web application. Earlier I was using Controller layer, Service layer(business logic), Model layer(entity) and DAO(DB) layer.
But someone pointed out that i should introduce two more layer ie. dto layer for collecting data from front end and transforming layer which will convert than dto into model(entity) layer objects.
Now I am using:
Controller layer (which will send the data to DTO layer)
DTO layer (which will send the its data to transforming layer)
Transforming layer(for converting dto layer objects into entity layer objects)
Service layer(Business logic)
Entity layer(POJO which will map with database)
DAO(which will use entity objects to store the database)
In this way we can keep front end and backend data different. Please help me out, is this a proper structure for Spring MVC ?
There is an interesting question answer thread on MVC here:https://softwareengineering.stackexchange.com/questions/127624/what-is-mvc-really
Some of the key points to remember when designing an application should be; layered and loosely coupled.
In your scenario, having additional transform layer does not necessarily make our break MVC pattern. It is just an additional layer you have introduced in MVC; a design strategy followed by many.
DTO is just a pattern to encapsulate data. Normally is used to be returned in your controllers, but you don't need always to create a DTO, you can use your entities for this. I just use a Dto when i need a different data structure, that any entity support, like a report for example.
About your project layers Model/Dao/Service/Controller it's correct, i strongly recommend for you the book Domain-driven design, it's will help you to build your software architectures!
But someone pointed out that i should introduce two more layer ie. dto layer for collecting data from front end and transforming layer which will convert than dto into model(entity) layer objects.
No, it's incorrect. You should use only layers that are necessary.
Earlier I was using Controller layer, Service layer(business logic), Model layer(entity) and DAO(DB) layer.
This is also incorrect. There's no strict definition of MVC is a pattern, but it's used only on one layer called a view layer, or in other terms presentation layer. Where the model, view, and controller reside. There's another layer called a service layer, which is optional. Then persistence layer, in this layer you model your objects and save them in the database or somewhere else. No more layers are necessary to the simple web application.
A few words about model, it's a set of classes that you want to persist or use in the view layer to show/store the data. Here you can play with it, because someone prefer to use it's own model to show/store the data, and others prefer their own model to persist it. These transformations are usually done in persistence or service, or in both layers. Keep in mind that all layers a loosely coupled to each other, but you can transfer data beans from one layer to another and back without problems. Entities in the detached state or other beans like DTOs are examples of such objects that you can pass and bake between layers. And no additional layers are necessary.
Related
You know that for an API project there are many patterns to retrieve and serve data to client. Controller <-> Service <-> Dao pattern is one of the these patterns.
Is it good to return any type of object from service layer or service layer return objects must be related entity?
For example, we have User, UserService, UserDao.
Should UserService return types be User or any type of object is suitable?
Having logical operations in service layer force me to use other objects as return type.
What is the best practice for that case?
I've found that I need 3 types of objects to keep things manageable (I'm still in a battle trying to come up with a decent naming strategy). It's sometimes beneficial to have:
Objects returned from your data layer - These objects will be dictated by your data implementation. For example, they could change if you decide to store your data differently. Perhaps you decide to serialise an object and store it as JSON rather than storing it in a separate table, or you move from SQL to NOSQL.
Objects returned from your domain layer - These are application objects and should model your domain. They shouldn't contain anything that is specific to your data implementation.
Objects sent to and from you API - It's useful to have separate serialisation objects to shape your API. It means you can tweak your API without having to touch the business logic. On some projects, I have multiple versions of the API objects for v1, v2 etc.
The widely accepted practise involve the service to have all business logic in it and return the Data Transfer Object(DTO)/ Business Object like User in your case. The Service may call DAO, any other datasources to fetch the entities, and a mapper/converter util can be used to convert the entities to DTO objects.
The DTO objects returned from Service can be embedded in a ResponseEntity(In the case of Spring MVC) and returned from the controller.
This makes your application into 3 separated layers like web, service, dataaccess. This supports design principles like Separation of Concerns, Single Responsibility. This also makes your unit testing and code management easier.
Could anyone suggest the best approach for sending data from controllers to service layer ?
I have UI <--> Controllers <--> Services <--> DAOs
I have models (or commands) to hold the data that user inputs in the UI to pass to controllers
I thought of creating models in controller layer , but don't want to pass them directly as service layer then depends on controller layer.
Do you suggest creating models in service layer and use them in controller layer ? But in this case these models will be used by jsps to serve data to the user ? is that ok ?
Could anyone suggest the best way in java to design the mvc layer shown above ?
Thanks
Ramesh
It's not necessarily wrong to serve domain model object directly to the UI layer, it's just that you tend quickly to run into a few common problems:
the view screen only needs a small subset of the model
certain fields like for example User.password you never want to send to the view layer
the domain model can contain loops, meaning object navigation paths in the object graph that go back to the initial object. This cannot be serialized correctly
lazy initialization exception on the domain model caused by detached objects
The common pattern to solve this is the DTO pattern, see here the description by Martin Fowler.
The common way to to it in larger applications is for the controller to send and received DTOs, and then do some mapping if needed to convert them into domain objects, this can be done for example with the Dozer mapping library.
On a smaller application this might not be justifiable, specially if you haven't encountered the problems mentioned above, although these tend to show up frequently.
Controllers take input from UIs and forward (hence the name Controller) the request to appropriate Model in tradional MVC pattern. But since you are using Spring MVC why not create your model objects in Spring context and use them is your service layer? You can use #Resource or #Autowired in service layer. Besides, if you want to reuse model objects you can easily do that because this way they are not locked into a particular layer. For eg., web service using your context.
Maybe others have a better way to do this.
In a standard Spring MVC application, where I have a Presentation layer, Controller layer, a Service layer, Repository/Persistence layer, which layer should be responsible for converting data retrieved from the DB to a DTO prior to sending to the presentation?
On one hand, I am thinking it should be at the Controller layer since it is specific to the data that is being required by the presentation, and is not "business logic" per se, however, on the other hand, I have nagging feeling that putting in intelligence (ie: knowing which fields to populate in the DTO) in the Controller is not really the job of the controller and should be relegated to the Service layer.
I realize that this may be a "gray" area, but is there a recommended practice?
I honestly do not know of a recommended practice, but I can tell you how it has been done in the projects I've worked on so far.
The Data (let's say Entity) is retrieved from the DB is mapped onto a corresponding Java class in an EntityMapper class, which relies of course in the Repository layer, because it is a DAO operation.
Any business logic applied on it should be tackled in the Service Layer, which passes it to the Controller.
The controller must return the data, but if you do not want to retrieve all the DB data (e.g. IDs, unnecessary columns, etc) which are in your Entity, you can convert them to a server-client DTO, meaning that you can have a similar EntityPresentation (silly name, I know) class, but with fewer fields, that will be communicated by the Controller to the presentation layer.
We are building an enterprise app that uses Spring MVC in presentation layer, EJB in business layer and JPA for data access. The app needs to support search function for various entities based on several search criteria, as entered by user from GUI. This seems to be fairly common function in most of the enterprise app, and I am wondering if there is any design pattern/principle that provides best approach.
For now, we are having SearchCriteria classes for each business entity (e.g. AccountSearchFilter for Account). Presentation layer builds the object of SearchCriteria class and pass it over to business layer. The business layer builds a JPA query based on the available criteria and creates a collection of entity objects. The collection is passed back to presentation layer, which is then transformed to JSON by presentation layer.
I have two problems with this design:
SearchCriteria classes are part of business layer, but they are used by presentation layer as well.
Business layer returns collections of business entities to presentation layer.
I don't like to share classes among presentation and business layers, but I don't know what we can do to decouple it. I have already searched the existing posts regarding using domain objects in presentation layer, and I don't want to start a debate whether it is good or bad. I have already made up my mind that I don't want presentation layer using domain objects. Also, creating DTOs seems to duplicate code, so if that is the only feasible solution, then I may pass on this one.
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.