4

I'm new to DDD and OO principles, sorry for my poor knowledge.

I have CustomerDTO and Customer classes.

I store all fields and properties in DTO class and use it as Base class for Customer class.

Main purpose of using DTO is to pass it to View. I've extended it in Customer class not to have duplication of properties.

Is it right way to do this or there's better OO solution?

I've read about AutoMapper, but I'd like to know, if there's alternative solution.

Many thanks for any kind of help.

hgulyan
  • 8,099
  • 8
  • 50
  • 75
  • 1
    Dto == structural, Do == behavioral. In what universe would they share a base class? – Yves Reynhout Jun 26 '12 at 21:28
  • DO == behavior + structure == behavior + Dto . This is how I thought it is. – hgulyan Jun 27 '12 at 04:27
  • 1
    DO = structured for **transactions**, DTO = structured for **querying** data to display on the UI. Their structures are and **should be** different. Trying to merge them together will lead to bad situation – David Masters Jun 27 '12 at 08:23
  • 1
    DTO are not about UI they are about crossing boundaries. Depending on what you mean by the view, you might be misusing DTO pattern: http://martinfowler.com/bliki/LocalDTO.html – Alex Burtsev Jun 28 '12 at 05:41
  • 1
    @AlexBurtsev DTOs have a specific reason to exist (and it's not to serve as models, as you correctly pointed out). However, describing them as "about crossing boundaries" is also wrong. They were introduced in the context of remote interfaces, specifically to mitigate the performance issues that arise when you have to make several calls to get the information you need (for example, a call to get the person, another to get the address). Instead of performing three calls, the service exposes one that returns a DTO with all information. http://martinfowler.com/eaaCatalog/dataTransferObject.html – Rui Oct 03 '13 at 17:18

4 Answers4

6

I have personally never seen this approach. The reason you use a DTO is to seperate concerns between the DAL and the biz layer. It lets the business layer and the DAL change at their own paces with minimal side effects. All you have to do is change the mappings between the DTO and DO. If you inherit your DO from your DTO, whats the point of even having a DTO?

Quick answer: do not inherit your DO from your DTO. It might be easy now, but it may be a maintanence nightmare in the future.

PS Don't be afraid of Automapper. Its relativly easy to use.

Ryan Bennett
  • 3,404
  • 19
  • 32
  • thank you for your clear answer. I was sure, that I'm wrong, but didn't know how to use DTO classes without duplicating properties. Isn't there a solution to avoid duplication? – hgulyan Jun 26 '12 at 20:17
  • Duplication is ok because they have two different purposes. They may be the same now, but if either needs to change, there will be no problem. Automapper will help with some of that pain of transferring data. Once you understand it, you'll be able to map 55 properties in two lines. – Ryan Bennett Jun 27 '12 at 13:57
  • @RyanBennett Describing DTOs like you did is wrong: http://martinfowler.com/eaaCatalog/dataTransferObject.html – Rui Oct 03 '13 at 17:21
2

This is a bad idea. Here are two reasons (there's probably a few more) why:

  • Domain Objects are specifically structured for transactions. They should not provide public access to all properties. They should only contain properties that provide behavioral purpose. DTO's have one purpose: to provide data to a consumer (such as a UI/Web Service/Message System). For example, a customer DTO may contain a properties that provide the number of orders that customer has made, and the total amount of money they have spent. On the domain side however, the Customer aggregate will probably not contain any of this information as this order information is stored in a separate order aggregate specifically tailored for order transactions.
  • DTO's are dumb POCO's with just a bunch of getters & setters. It is very bad practice to allow your domain objects to have setters on all of their properties. Operations should be atomic and provided by methods that have explicit names describing their intent. The answer to this question explains this point.
Community
  • 1
  • 1
David Masters
  • 8,069
  • 2
  • 44
  • 75
  • DTO's are not only about UI,web services and message buses are primary "consumers" of DTO – Alex Burtsev Jun 28 '12 at 04:33
  • Very nice answer. I agree with you, that domain object shouldn't have access to some of DTO's properties. Main reason for reusing dto in domain object is to avoid duplication, but on the other side it leads to some problems you mentioned. – hgulyan Jun 28 '12 at 05:55
  • @AlexBurtsev that is indeed true, but just semantics and not my point. My point is: DO's are designed for concurrent state changing transactions, with data encapsulated behind atomic operations. They should not simply be a DTO + some methods. – David Masters Jun 28 '12 at 08:08
1

Expanded Answer:

Let's try analyze this situation, without blindly saying that no one do such a thing.

DTO - it's structures that contain only data and transfer it between boundries.

Domain Model - the key word here is 'Model' is an abstraction of you domain that solve it's problems. From an OO view it's simple class, if you break it apart it would be pure data (DTO), and pure stateless behavior (Service or Domain Service in DDD terms).

Now let's take for example MVVM pattern, particularly it's VM part. View Model - the key word here is again 'Model' is an abstraction of view that solve it's problems. There are lot's of way people implement it, some wrap Domain Objects, some do conversion, some wrap DTO's. The point here is that View Model is a Domain Model of the view, it's pretty much the same as any Model. Then why do people restrict there way to implement Domain Model.

Now back to DTO and Domain Model. As I said above we can break down Domain Object to DTO and Service. Let's consider we think of Domain object as a behavioral wrapper around DTO (like MVVM often does). Where it lead's us:

  • First we break OO encapsulations. This is bad because because it prevents our object data from incorrect usage. Someone could take our Domain object data (DTO) manipulate it directly and put our Model in invalid state. This is huge.
  • We can easily transfer our object throw boundaries, web services, serialization, cloning, we can detach out data part, and give it to our data storage or web service. This is huge for distributed systems.

Let's continue, breaking encapsulation is a serious problem. What we need is a way to guarantee that our Domain Object data will not be manipulated directly, only Domain Object should manipulate it. We can achieve this by making DTO immutable, read only object, when it's outside of Domain Object.

Now about reusing DTO, Inheritance vs Composition. Someone said: prefer composition over inheritance, and i personally do follow this rule. But you need to analyse your particular situations. The rule say 'prefer' not obey.

Original Asnwer:

Though I didn't personally seen such approach too often, I think this method is underestimated and it could be potentially very good.

I seen such questions asked many times, and all the answers were, do not do this because nobody do such things. Do not be afraid to experiment.

Ryan Bennet wrote in his answer:

It might be easy now, but it may be a maintanence nightmare in the future.

Well it's true, but what if there will be no future or it's small project, I would stick to YAGNI, TDD and Agile rules here, and do minimal work that does the job.

Code isn't something you engrave in stone and never touch, when you need you can refactor, and introduce DTO, use auto-mapper or whatever.

Alex Burtsev
  • 12,418
  • 8
  • 60
  • 87
  • Nice to hear, that this solution isn't that bad :D Well, it's a big project(not a small one at least) and refactoring would be very hard after we finish it. Besides that there's another problem I'm afraid of. My domain object won't be able to extend any other class. On the other side I don't like the fact of duplicating properties. – hgulyan Jun 27 '12 at 06:26
  • I'm using similar approach right now in middle size project (10 developers team, 300-400 distributed machines participating in message bus). But I prefer composition over inheritance. My Domain model (objects) contain DTO and add behavior (methods) above them. – Alex Burtsev Jun 27 '12 at 06:49
  • Interesting solution. Maybe I could try it in my project, but anyway you should have getters and setter in both classes. – hgulyan Jun 27 '12 at 07:18
  • I don't think encouraging someone to go ahead with a solution that's widely regarded as bad practice is good advice, personally. – David Masters Jun 27 '12 at 15:06
  • @DavidMasters I would agree with you just a few months ago, and I would consider my current ansther as a total heresy. But you should stop BLINDLY following rules (practices) that have been grown by community and noone even knows why they should follow them. Free you mind, "there is no spoon". I would exapnd my answer. – Alex Burtsev Jun 28 '12 at 04:30
  • Very nice points. The best and detailed answer, but I think I will go for duplicating, because of some disadvantages in both composition and inheritance solutions. I agree with you that just following rules is wrong. After I see the whole picture, I can make my choice. Thanks. – hgulyan Jun 28 '12 at 06:04
  • @hgulyan What disadvantages have you considered? – Alex Burtsev Jun 28 '12 at 06:50
  • For example, I can have some properties in DTO, that shouldn't be part of Domain Object. Another thing is that I can have some properties, that should have setters only in Domain Object. I suppose, there're some other problems with DTO, so it's easier for me just to duplicate some of properties and using automapper. – hgulyan Jun 28 '12 at 08:25
0

Old question, and I like several other answers here, particularly about separating the DAL from the business layer. HOWEVER, I'd like to mention a concrete issue that you might encounter when having DO classes inherit from DTO classes.

In .NET languages such as C# and VB, you cannot have true multiple inheritance. That is a class cannot extend two base classes. Therefore, if your DO class already extends a DTO base class, then you have precluded the possibility of inheritance between the DO class and another DO class.

Ignoring what the tables look like that actually persist the data or whether you use TPH, TPT, or TPC, imagine you have DO classes for

Vehicle
Car : Vehicle
Boat : Vehicle

You cannot have Car : CarDto, Vehicle. If you project is complex enough to have any inheritance between DO classes, then this is a pretty compelling argument by itself.

Finally, I'd like to just add that when choosing between inheritance vs. composition, you think in terms of "is a" vs. "has a". So what makes more sense: "Car is a CarDto" or "Car is a Vehicle"? The latter IMO.

Community
  • 1
  • 1
neizan
  • 2,291
  • 2
  • 37
  • 52