Plain Old CLR Object vs Data Transfer Object

后端 未结 10 1449
挽巷
挽巷 2020-11-22 13:38

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 P

相关标签:
10条回答
  • 2020-11-22 14:00

    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.

    0 讨论(0)
  • 2020-11-22 14:00

    here is the general rule: DTO==evil and indicator of over-engineered software. POCO==good. 'enterprise' patterns have destroyed the brains of a lot of people in the Java EE world. please don't repeat the mistake in .NET land.

    0 讨论(0)
  • 2020-11-22 14:05

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

    In short:

    • DTO != Value Object
    • DTO ⊂ POCO
    • Value Object ⊂ POCO
    0 讨论(0)
  • 2020-11-22 14:07

    TL;DR:

    A DTO describes the pattern of state transfer. A POCO doesn't describe anything. 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.

    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. It just means it's a CLR object with no implied pattern to it. A generic term. It 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.

    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. In MVVM, it also acts as a controller. It's more than a DTO
    • Value Object: used to represent values
    • Aggregate Root: used to manage state and invariants
    • Handlers: used to respond to an event/message
    • Attributes: used as decorations to deal with cross-cutting concerns
    • Service: used to perform complex tasks
    • Controller: used to control flow of requests and responses
    • 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

    These are all just objects, but notice that most of them are generally tied to a pattern. 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 works. DTO is a pattern. Aggregate root is a pattern, View Model is a pattern (e.g. MVC & MVVM). POCO is not a pattern.

    A POCO doesn't describe a pattern. It is just a different way of referring to classes/objects in OOP. 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, it is no longer a POCO. Therefore:

    • A DTO is a POCO
    • A POCO is not a DTO
    • A View Model is a POCO
    • A POCO is not a 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.

    0 讨论(0)
  • 2020-11-22 14:08

    It's probably redundant for me to contribute since I already stated my position in my blog article, but the final paragraph of that article kind of sums things up:

    So, in conclusion, learn to love the POCO, and make sure you don’t spread any misinformation about it being the same thing as a DTO. DTOs are simple data containers used for moving data between the layers of an application. POCOs are full fledged business objects with the one requirement that they are Persistence Ignorant (no get or save methods). Lastly, if you haven’t checked out Jimmy Nilsson’s book yet, pick it up from your local university stacks. It has examples in C# and it’s a great read.

    BTW, Patrick I read the POCO as a Lifestyle article, and I completely agree, that is a fantastic article. It's actually a section from the Jimmy Nilsson book that I recommended. I had no idea that it was available online. His book really is the best source of information I've found on POCO / DTO / Repository / and other DDD development practices.

    0 讨论(0)
  • 2020-11-22 14:10

    A primary use case for a DTO is in returning data from a web service. In this instance, POCO and DTO are equivalent. Any behavior in the POCO would be removed when it is returned from a web service, so it doesn't really matter whether or not it has behavior.

    0 讨论(0)
提交回复
热议问题