views:

85

answers:

6

Assuming a "standard" 3-tier application (UI - Domain - Data), should the Domain Layer show to the UI classes originally defined in the Data Layer?

I mean, assuming there's a Product class defined in the Data Layer, is it wrong to make some method from my Domain Layer have methods returning it (this is, making them visible to the UI)? Or should I define in the Domain Layer itself some class that wraps the Product from the Data Layer, so the UI now doesn't depend on the Data Layer?

Thanks

A: 

It depends on your architecture. For example, if you're using the MVVM pattern (Model-View-ViewModel) you have to define UI model classes in the middle.

sukru
+5  A: 

You usually have a Product interface and a ProductImpl. The UI only knows of the interface and is perfectly decoupled from the Data layer (which uses the implementation class).

Andreas_D
But my question is, shouldn't the UI use only interfaces/classes from the domain model?
devoured elysium
Hard to tell - I know of one big 3-tier application where the interfaces are part of the data access layer (they use DTO pattern). So in this application, the UI client is loosely coupled with the data layer - what I definitly don't like, because servicing the data layer almost always affects the whole application up to the UI.
Andreas_D
I don't get it. Shouldn't the UI and Data Layers be loosely coupled?
devoured elysium
+1  A: 

This kind of implementation binds the UI classes to data classes which generally is harmful. A better practice in all known scenario is to keep them separate. This will not only decouple them from each other but also give you the freedom to insert custom logic (anytime in future) between UI classes and data classes. It also gives you freedom to do customizations to data object without affecting the UI classes directly.

Tushar Tarkas
So, the idea is that the UI Layer doesn't even know there is a Data Layer, right?
devoured elysium
absolutely. that is why the abstraction.
Tushar Tarkas
A: 

The answer on this question strongly depends on what the domain layer exactly does.

If you've got nearly no or no logic in the domain layer, in 90% of all cases, there is no need to use different objects then defined in the data layer.

If you have a simple product class, which only holds values for passing data between Data Layer and UI and so on, it should be pretty safe to use them. You have only to be careful if the domain layer does much additional processing and some parts of objects of the data layer should not be exposed to the UI.

One thing you should do is to define an Interface for your Data Layer and only work with this interface, so you can make the Data Layer independent and switch quickly between different data sources if needed.

Emiswelt
A: 

In concept the attributes required by the UI are derived from those held in the Data layer, but they are not identical to them. We enrich the data, for example adding reference data or derived values or combining items from different classes or perhaps denormalising data to make it easier to present. So in the most general case the UI data model and the persistence data model are different.

In really simple cases, especailly the sort of things I do in demonstration code there is little or no difference between the two models and if you do create a new set of classes you just end up with complete duplication. I think in this case Andreas_D's point about creating an Interface defining what the UI needs, and which may well initially be directly implemented by the Data layer is a nice compromise. It very clearly demarks the UI's interests and the Data Layer's responsibilities.

djna
Shouldn't the attributes of the UI be derived from the DOMAIN/MODEL Layer, not the Data Layer?
devoured elysium
@devoured Yes, that's right. There's a couple of levels of derivation. And in the extreme simple cases the data's the same all the way up.
djna
A: 

Is a Product domain class? How do you get Product class in UI tier? Do you really mean 3-tier? A tier is physical boundary so 3-tier means that UI / BL / DB are three different processes.

If you use Product as domain class (= data + logic) you should not share it with UI and you should create new data transfer object (DTO) instead. DTO transfers only needed information between two tiers.

If you don't share assembly / package with Product domain class with UI and instead you are creating new class from WSDL you can use Product domain class in your exposed service - serialization will transfer only data not logic.

If you use Product as pure container for data, you have already created DTO and you can share assembly / package with this class among tiers.

Ladislav Mrnka