A one possible structure for an application is to have it broken down into modules such as Data Access, Core, Services, UI. Now depending on what type of ORM you are using Data Access layer will have a set of entities that represent the tables in the database. The core layer will have a set of entities that represent the business logic. The service layer will have a set of DTO entities that it will communicate with to the UI. And finally the UI will have a set of View Models that it will use inside the views.
Now when we access or store information in the database we have to transform objects from one type to another. When the service calls the core it needs to transform objects from one type to another and finally the UI needs to transform the DTO’s to View Models. In a lot of the cases the transformation is a simple act of copying the properties from one object to another. It is a very repetitive and time consuming task that generates large amounts of code.
My question is am I doing something wrong here. Should I only have one entity type? If so don’t you think that it would have too much information in one object for data access, business logic etc… Is there a quick way to copy the properties between objects? Reflection is an option but gets complicated fast when dealing with object graphs? I know there is no silver bullet to fix this problem but there must be a number of good approaches over copying the properties by hand between the entities?
3
I hate the idea of parallel object hierarchies just for the sake of layer purity.
This is a Core J2EE Pattern that in my view has become an anti-pattern. People used to create DTOs because the EJB 1.0 entity model was too chatty. I think POJOs/POCOs are smarter and don’t have to resort to such contortions.
The data access layer might represent tables or objects, depending on which way you go.
The service layer maps to use cases and units of work. It owns transactions and orchestrates processes to fulfill the wishes of clients. It should be UI agnostic.
I’d recommend creating model objects and using them appropriately. Just make sure that you find a way to avoid cyclic dependencies between packages/namespaces. Don’t couple all of them together. Data access layer should know about model objects but nothing else. Service layer should know about data access layer, model objects, other services and nothing else. View layer should have controllers that invoke services and nothing else.
With your architecture, yes you should have multiple objects.
Always start with the domain entity as it’s the primary reason for creating your application.
A service layer is created to allow the outside world to talk with your application. The api in it may or may not look exactly as your domain entities. My experience is the API diverges from the underlying model as the application grows. The DTOs are used to transfer information over process boundries and therefore to decouple the API from the model that it’s a facade for. You might also want to flatten the entity, use strings instead of enums etc.
In the database you might not be able to store the information in the same way as your domain entity is modeled. You might want to denormalize to decrease the number of joins, or normalize to use less space. It all depends on the situation, and it might also vary from entity to entity.
A view might contain information from multiple entities. For instance for a user and a message. Hence the view model is combination of both of the entities. The view model may also have logic used to calculate something that the view requires. Placing that logic inside the view would make it a lot harder to test that logic.
As for streamlining the process, I would say no. There are tools like AutoMapper and similar which do the copying for you. But the problem with those is that you’ll never know if you’ve missed something in the configuration (as they usually work by conventation and not by manual configuration). So you might refactor a field in the DTO but not in the entity resulting in that field not being copied. It’s much more robust to create converter classes by hand (as they also allow you to do transformations).
I’ve personally used tools like that, but on the long run I also find myself wondering if it wouldn’t have gone faster if I simply had created the convert classes myself. And that’s why I’ve also stopped using libraries like that.
What I’m saying is that all different representations might seem the same at first glance, but they all have small differences that you must address. If you use the same representation for all layers you have to do compromises to make it work in all layers. Your entity quality will decrease the longer you maintain the application.
I would rather ask you if you need that service layer? Is your application complex enough mandating it? Do you need to use a RDBMS instead of a schemaless DB?
I hate the idea of directly mapping your DB to objects and passing them around like theyre properties on a class (which we know is an anti-pattern itself)
The best way to model your application is to split it into tiers, then think what each tier requires and provides, independantly of the other tiers. ie, do not start making your UI and think of the database at all. Think what services your UI needs, these will then be mapped to a application tier that itself will require services.These services then get modelled in the DB (preferably as stored procedures so you get a nice DB API), those sprocs can then be modelled onto whatever data model you like.
The reason to do this is that it makes you think in terms of the application requirement, not the implementation. Once you start thinking of passing objects around, you’re tying yourself into a fixed implementation or worse – like security issues as well (eg when it becomes just a little too convenient to access the DB directly from the UI, people will do so).
0