Plain Old CLR Object vs Data Transfer Object

149,485

Solution 1

A POCO follows the rules of OOP. It should (but doesn't have to) have state and behavior. POCO comes from POJO, coined by Martin Fowler [anecdote here]. He used the term POJO as a way to make it more sexy to reject the framework heavy EJB implementations. POCO should be used in the same context in .Net. Don't let frameworks dictate your object's design.

A DTO's only purpose is to transfer state, and should have no behavior. See Martin Fowler's explanation of a DTO for an example of the use of this pattern.

Here's the difference: POCO describes an approach to programming (good old fashioned object oriented programming), where DTO is a pattern that is used to "transfer data" using objects.

While you can treat POCOs like DTOs, you run the risk of creating an anemic domain model if you do so. Additionally, there's a mismatch in structure, since DTOs should be designed to transfer data, not to represent the true structure of the business domain. The result of this is that DTOs tend to be more flat than your actual domain.

In a domain of any reasonable complexity, you're almost always better off creating separate domain POCOs and translating them to DTOs. DDD (domain driven design) defines the anti-corruption layer (another link here, but best thing to do is buy the book), which is a good structure that makes the segregation clear.

Solution 2

POCO is simply an object that does not take a dependency on an external framework. It is PLAIN.

Whether a POCO has behaviour or not it's immaterial.

A DTO may be POCO as may a domain object (which would typically be rich in behaviour).

Typically DTOs are more likely to take dependencies on external frameworks (eg. attributes) for serialisation purposes as typically they exit at the boundary of a system.

In typical Onion style architectures (often used within a broadly DDD approach) the domain layer is placed at the centre and so its objects should not, at this point, have dependencies outside of that layer.

Solution 3

I wrote an article for that topic: DTO vs Value Object vs POCO.

In short:

  • DTO != Value Object
  • DTO ⊂ POCO
  • Value Object ⊂ POCO

Solution 4

I think a DTO can be a POCO. DTO is more about the usage of the object while POCO is more of the style of the object (decoupled from architectural concepts).

One example where a POCO is something different than DTO is when you're talking about POCO's inside your domain model/business logic model, which is a nice OO representation of your problem domain. You could use the POCO's throughout the whole application, but this could have some undesirable side effect such a knowledge leaks. DTO's are for instance used from the Service Layer which the UI communicates with, the DTO's are flat representation of the data, and are only used for providing the UI with data, and communicating changes back to the service layer. The service layer is in charge of mapping the DTO's both ways to the POCO domain objects.

Update Martin Fowler said that this approach is a heavy road to take, and should only be taken if there is a significant mismatch between the domain layer and the user interface.

Solution 5

TL;DR:

A DTO describes the pattern of state transfer. A POCO doesn't describe much of anything except that there is nothing special about it. It's another way of saying "object" in OOP. It comes from POJO (Java), coined by Martin Fowler who literally just describes it as a fancier name for 'object' because 'object' isn't very sexy and people were avoiding it as such.

Expanding...

Okay to explain this in a far more high-brow way that I ever thought would be needed, beginning with your original question about DTOs:

A DTO is an object pattern used to transfer state between layers of concern. They can have behavior (i.e. can technically be a poco) so long as that behavior doesn't mutate the state. For example, it may have a method that serializes itself.

A POCO is a plain object, but what is meant by 'plain' is that it is not special and does not have any specific requirements or conventions. It just means it's a CLR object with no implied pattern to it. A generic term. I've also heard it extended to describe the fact that it also isn't made to work with some other framework. So if your POCO has [JsonProperty] or EF decorations all over it's properties, for example, then it I'd argue that it isn't a POCO. POCOs are free and unencumbered like the objects you learn to create in school

Here some examples of different kinds of object patterns to compare:

  • View Model: used to model data for a view. Usually has data annotations to assist binding and validation for particular view (i.e. generally NOT a shared object), or in this day and age, a particular view component (e.g. React). In MVVM, it also acts as a controller. It's more than a DTO; it's not transferring state, it's presenting it or more specifically, forming that state in a way that is useful to a UI.
  • Value Object: used to represent values, should be immutable
  • Aggregate Root: used to manage state and invariants. should not allow references to internal entities other than by ID
  • Handlers: used to respond to an event/message.
  • Attributes: used as decorations to deal with cross-cutting concerns. May only be allowed to be used on certain objects levels (e.g. property but not class, method but not property, etc.)
  • Service: used to perform complex tasks. Typically some form of facade.
  • Controller: used to control flow of requests and responses. Typically restricted to a particular protocol or acts as some sort of mediator; it has a particular responsibility.
  • Factory: used to configure and/or assemble complex objects for use when a constructor isn't good enough. Also used to make decisions on which objects need to be created at runtime.
  • Repository/DAO: used to access data. Typically exposes CRUD operations or is an object that represents the database schema; may be marked up with implementation specific attributes. In fact, one of these schema DAO objects is actually another kind of DTO...
  • API Contracts: Likely to be marked up with serialization attributes. Typically needs to have public getters and setters and should be lightweight (not an overly complex graph); methods unrelated to serialization are not typical and discouraged.

These can be seen as just objects, but notice that most of them are generally tied to a pattern or have implied restrictions. So you could call them "objects" or you could be more specific about its intent and call it by what it is. This is also why we have design patterns; to describe complex concepts in a few words. DTO is a pattern. Aggregate root is a pattern, View Model is a pattern (e.g. MVC & MVVM).

A POCO doesn't describe a pattern. It is just a different way of referring to classes/objects in OOP which could be anything. Think of it as an abstract concept; they can be referring to anything. IMO, there's a one-way relationship though because once an object reaches the point where it can only serve one purpose cleanly, it is no longer a POCO. For example, once you mark up your class with decorations to make it work with some framework (i.e. 'instrumenting' it), it is no longer a POCO. Therefore I think there are some logical relationships like:

  • A DTO is a POCO (until it is instrumented)
  • A POCO might not be a DTO
  • A View Model is a POCO (until it is instrumented)
  • A POCO may not be View Model

The point in making a distinction between the two is about keeping patterns clear and consistent in effort to not cross concerns and lead to tight coupling. For example if you have a business object that has methods to mutate state, but is also decorated to hell with EF decorations for saving to SQL Server AND JsonProperty so that it can be sent back over an API endpoint. That object would be intolerant to change, and would likely be littered with variants of properties (e.g. UserId, UserPk, UserKey, UserGuid, where some of them are marked up to not be saved to the DB and others marked up to not be serialized to JSON at the API endpoint).

So if you were to tell me something was a DTO, then I'd probably make sure it was never used for anything other than moving state around. If you told me something was a view model, then I'd probably make sure it wasn't getting saved to a database. If you told me something was a Domain Model, then I'd probably make sure it had no dependencies on anything outside of the domain. But if you told me something was a POCO, you wouldn't really be telling me much at all other than it is not and should not be instrumented.

History

Paraphrased from Fowler's explanation: In a world where objects were fancy (e.g. followed a particular pattern, had instrumentation etc.), it somehow encouraged people to avoid using not-fancy objects to capture business logic. So they gave it a fancy name POJO. If you want an example, the one he refers to is an "Entity Bean" which is one of those kinds of objects that have very specific conventions and requirements, etc.. If you don't know what that is --> Java Beans.

In contrast, a POJO/POCO is just the regular ole object that you'd learn out to create in school.

Share:
149,485
TestyTest
Author by

TestyTest

Senior .NET C# developer and technical architect.

Updated on July 08, 2022

Comments

  • TestyTest
    TestyTest almost 2 years

    POCO = Plain Old CLR (or better: Class) Object

    DTO = Data Transfer Object

    In this post there is a difference, but frankly most of the blogs I read describe POCO in the way DTO is defined: DTOs are simple data containers used for moving data between the layers of an application.

    Are POCO and DTO the same thing?

  • John Saunders
    John Saunders about 15 years
    Could you elaborate, please? DTO are required when returning data from a web service, in order to avoid implementation and platform specifics in the contract.
  • Michael Meadows
    Michael Meadows about 15 years
    I know I referenced Martin Fowler a lot here, but he coined the term POJO, and wrote the book PoEAA that is the definitive reference for DTO.
  • Craig
    Craig about 15 years
    Yes, John DTO's are designed for what you say and work well. But unfortunately they often get used when not required in single tier web apps and have little value.
  • Michael Meadows
    Michael Meadows almost 15 years
    I think your answer misrepresents what happens a little. In the case of a web service, a proxy is generated based on the exposed state of an object. This means a DTO is created separate from the POCO that just happens to have the same public state as the POCO. It may seem subtle, but it's important. The reason is that even if the proxy is identical to the original, it's not actually constructed from the same class.
  • Michael Meadows
    Michael Meadows almost 15 years
    I think, @drscroogemcduck, that maybe you dislike DTOs because they're used as a first resort rather than a last resort, but they're not inherently evil... no more so than the infamous singleton or factory patterns. What is evil are the architects who shove frameworks down developers' throats that force them to make DTOs for everything. For what they do, transferring data, DTOs (if done prudently) are the perfect fit.
  • Michael Meadows
    Michael Meadows almost 15 years
    @David Landman, the link you included is for the Local DTO pattern, which is when DTOs are used for transfer state within your system boundary. In these cases, you should be very careful, since within your system you should already have a well defined domain that can be shared. When transferring state across system boundaries, the DTO is hard to avoid and pretty appropriate in all cases.
  • John Saunders
    John Saunders almost 15 years
    Uh, no. One uses a DTO to return / receive data between tiers, in this case, a web service. One chooses a DTO because it has only data, and no behavior. It's true that the proxy class will also likely be a DTO, and that if you had used a POCO class instead, that a proxy would have been created. But in this case, the POCO class is effectively a DTO, since its behavior will not translate. I still say use a DTO because you won't miss behavior that never existed.
  • Michael Meadows
    Michael Meadows almost 15 years
    @John Saunders, Sorry if I wasn't clearer. I'm not arguing with the validity of your argument, but instead with the semantics of it. ** To your point: A DTO is meant to protect your POCOs from what you describe. In order for this to happen, DTOs must be mapped to the POCO. In simple to moderately complex solutions, this may be overkill, and therefore you're correct.
  • Michael Meadows
    Michael Meadows almost 15 years
    ** Semantically: Web services expose object state bags using WSDL. Proxies are generated from these. These cannot include behavior. If consuming a web service, the only relationship between your object and the exposed domain object is that it has the same public state created based on inspection.
  • John Saunders
    John Saunders almost 15 years
    @Michael: I have no idea what you're talking about. If you want that to change, then please post some citations or something. I've been using DTOs in web services for a while, and it was never in order to protect any POCO. It was in order to Transfer Data in an Object.
  • Michael Meadows
    Michael Meadows almost 15 years
    @John, I think you're overreacting. I'm saying you're right, but your wording is misleading. "In this case, POCO and DTO are equivalent." Semantically, that's not true. POCOs can be used as DTOs and vice versa, but that doesn't mean they're equivalent... no more than a car and pickup truck are equivalent, even though they can both be used to drive you to the grocery store. They have overlapping function, but you'd be hard pressed to find someone to tell you an insight is equivalent to an F350, even in the context of the grocery trip.
  • Naveed
    Naveed almost 15 years
    @Michal Meadows, yes, the link does indeed talk about a different subset of problems. But I think in the case of transferring state across a system boundary you should use a translation service to map the POCO from one context to the POCO from other context. Or are you talking about bounderies on a system level?
  • Beatles1692
    Beatles1692 almost 15 years
    I'm not sure if a DTO should not have behaviors.Judging by Martin Fowler's diagram ,DTO could have behaviors.
  • Michael Meadows
    Michael Meadows almost 15 years
    @Beatles1692, the methods depicted are serialization code. It's probably too broad of a statement to say "no behavior." How about "no business logic." Serialization code, and low level object stuff like hash code, equality, and tostring should be acceptable.
  • Tom Stickel
    Tom Stickel over 12 years
    This answer is so very wrong, a web service is not generic enough for one. Most importantly it is a well established fact that DTO is NOT a POCO. DTO is a data container, while POCO are objects as properties and are persistence ignorant (no get or save methods).
  • TestyTest
    TestyTest about 12 years
    I also found a nice Assembly pattern from Microsoft to decouple DTO and business objects(POCO): msdn.microsoft.com/en-us/library/ms978717.aspx
  • PositiveGuy
    PositiveGuy about 9 years
    don't even call them DTOs. They're called Models. DTOs are stupid terms to put on these.
  • Gerald
    Gerald about 9 years
    i don't know where you got this idea that models never have behavior. How do you model anything other than CRUD without modeling behavior? Even ViewModels have behavior in many cases, particularly in MVVM apps. DTO is a useful term because it accurately describes the purpose; to transfer data.
  • joedotnot
    joedotnot about 9 years
    downvoted for being factually incorrect, and for the pontificating attitude.
  • PositiveGuy
    PositiveGuy about 9 years
    Nonsense. Models should be stupid containers. There is no DTO, it's a MS made up term. You transfer models between domains, services, and apps. Period. DTO is a waste of term that's not needed and only confuses things more. Models, Models and more Models that's it. Models may or may not have behavior. View Models should not. That behavior should be in a BL, not in the Model class.
  • SQLMason
    SQLMason over 8 years
    I agree that DTO's are functionally Models. ViewModels have behavior and is what you bind to in MVVM. HOWEVER, I wrote an app where my Models were more intelligent (basically VMs but I didn't want to call them than) and they "accepted" a DTO object. This allowed me to have more options with the framework. So from CRUD (or even EF), I would transmit the object over WCF services and receive the DTO object and encapsulate it (adding OnProp Change, etc). My ViewModels performed further encapsulation and may have accepted two (or a list) of "Models". The rigid definition would be VMs.
  • caa
    caa over 8 years
    "You transfer models between domains, services, and apps" Why do think the term model is more appropriate and fitting than the term DTO for this behaviour you describe?
  • KCD
    KCD over 7 years
    @MSSucks in MVC Models often hold business logic so the term "DTO" is less likely to be interpreted differently
  • Michael Meadows
    Michael Meadows about 7 years
    @PositiveGuy A model serves a different purpose from a DTO. DTO should be for transferring data from one domain to another (whether or not they're in the same runtime is irrelevant). A model "represents" an aspect of a domain, like a screen, service, or data source. Models include state and behavior, that are representative of what they're modeling.
  • Mariusz Jamro
    Mariusz Jamro over 5 years
    Please note that anemic domain models are not necessarily bad, especially if your app is mostly CRUD. Favor simplicity over Martin Fowler.
  • Herman Van Der Blom
    Herman Van Der Blom over 2 years
    Its not Evil. It all comes down on good design. With bad design you indeed will overengineer. You will see that if everything in a web site is a Serviceable. Put everything in a DomainModel and aggregate where possible. Its wrong to create objects for everything.