Why should I isolate my domain entities from my presentation layer?

Solution 1:

Quite simply, the reason is one of implementation and drift. Yes, your presentation layer needs to know about your business objects to be able to represent them properly. Yes, initially it looks like there is a lot of overlap between the implementation of the two types of objects. The problem is, as time goes on, things get added on both sides. Presentation changes, and the needs of the presentation layer evolve to include things that are completely independent of your business layer (color, for example). Meanwhile, your domain objects change over time, and if you don't have appropriate decoupling from your interface, you run the risk of screwing up your interface layer by making seemingly benign changes to your business objects.

Personally, I believe the best way to approach things is through the strictly enforced interface paradigm; that is, your business object layer exposes an interface that is the only way that it can be communicated with; no implementation details (i.e. domain objects) about the interface are exposed. Yes, this means that you have to implement your domain objects in two locations; your interface layer and in your BO layer. But that reimplementation, while it may initially seem like extra work, helps enforce the decoupling that will save TONS of work at some point in the future.

Solution 2:

I have struggled with this myself. There are cases where a DTO makes sense to use in presentaton. Let's say I want to show a drop down of Companies in my system and I need their id to bind the value to.

Well instead of loading a CompanyObject which might have references to subscriptions or who knows what else, I could send back a DTO with the name and id. This is a good use IMHO.

Now take another example. I have an object which represents an Estimate, this estimate might be made up labor, equipment etc, it might have lots of calculations that are defined by the user which take all these items and sum them up (Each estimate could be different with different types of calculations). Why should I have to model this object twice? Why can't I simply have my UI enumerate over the calculations and display them?

I generally do not use DTO's to isolate my domain layer from my UI. I do use them to isolate my domain layer from a boundary that is outside of my control. The idea that someone would put navigation information in their business object is ridiculous, don't contaminate your business object.

The idea that someone would put validation in their business object? Well I say that this is a good thing. Your UI should not have sole responsability to validate your business objects. Your business layer MUST do its own validation.

Why would you put UI generation code in a busienss object? In my case I have seperate objects which generates the UI code seperatley from the UI. I have sperate objects which render my business objects into Xml, the idea that you have to seperate your layers to prevent this type of contamination is so alien to me because why would you even put HTML generation code in a business object...

Edit As I think a little bit more, there are cases where UI information might belong in the domain layer. And this might cloud what you call a domain layer but I worked on a multi-tenant application, which had very different behavior both UI look and feel and functional workflow. Depending on various factors. In this case we had a domain model that represented the tenants and their configuration. Their configuration happened to include UI information (Label's for generic fields for example).

If I had to design my objects to make them persistable, should I also have to duplicate the objects? Keep in mind if you want to add a new field now you have two places to add it. Perhaps this raises another question if your using DDD, are all persisted entities domain objects? I know in my example they were.

Solution 3:

You do it for the same reason you keep SQL out of your ASP/JSP pages.

If you keep only one domain object, for use in the presentation AND domain layer, then that one object soon gets monolithic. It starts to include UI validation code, UI navigation code, and UI generation code. Then, you soon add all of the business layer methods on top of that. Now your business layer and UI are all mixed up, and all of them are messing around at the domain entity layer.

You want to reuse that nifty UI widget in another app? Well, You have to create a database with this name, these two schemas, and these 18 tables. You must also configure Hibernate and Spring ( or your frameworks of choice ) to do the business validation. Oh, you must also include these 85 other non-related classes because they are referenced in the business layer, which just happens to be in the same file.

Solution 4:

I disagree.

I think the best way to go is to start with domain objects in your presentation layer UNTIL IT MAKES SENSE TO DO OTHERWISE.

Contrary to popular belief, "Domain Objects" and "Value Objects" can happily co-exist in the presentation layer. And this is the best way to do it - you get the benefit of both worlds, reduced duplication (and boilerplate code) with the domain objects; and the tailoring and conceptual simplification of using value objects across requests.

Solution 5:

Answer depends on scale of your application.


Simple CRUD (Create, Read, Update, Delete) application

For basic crud applications you do not have any functionality. Adding DTO on top of entities woudl be a waste of time. It would increase complexity without increasing scalability.

enter image description here


Moderately complicated Non-CRUD application

In this size of application you will have few entities which have true lifeclycle and some business logic associated with them.

Adding DTOs on this case is a good idea for few reasons:

  • Presentation layer can see only subset of fields which entity has. You encapsulate Entities
  • No coupling between backend and frontent
  • If you have business methods inside entities, but not in DTO then adding DTOs means that outside code can't ruin state of your entity.

enter image description here


Complicated Enterprise Application

Single entity might need multiple ways of presentation. Each of them will need different set of fields. In this case you encounter the same issues as in previous example plus need to control amount of fields visible for each client. Having separate DTO for each client will help you to chose what should be visible.

enter image description here