POCO =普通旧CLR(或更好的:类)对象
DTO =数据传输对象
在这篇文章中有一个区别,但坦率地说,我读过的大多数博客都是用DTO的定义方式描述POCO的:DTO是简单的数据容器,用于在应用程序的层之间移动数据。
POCO和DTO是同一个东西吗?
POCO =普通旧CLR(或更好的:类)对象
DTO =数据传输对象
在这篇文章中有一个区别,但坦率地说,我读过的大多数博客都是用DTO的定义方式描述POCO的:DTO是简单的数据容器,用于在应用程序的层之间移动数据。
POCO和DTO是同一个东西吗?
当前回答
TL; diana:
DTO描述状态传输的模式。POCO并没有描述太多东西,除了它没有什么特别之处。这是OOP中“对象”的另一种说法。它来自POJO (Java),由Martin Fowler创造,他只是把它描述为“对象”的一个更花哨的名字,因为“对象”不是很性感,人们都在回避它。
扩大……
好吧,用一种我认为需要的更高尚的方式来解释这个问题,从你最初关于dto的问题开始:
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. For it to be a proper DTO, it needs to be a simple property bag; it needs to be clear that this object is not a strong model, it has no implied semantic meaning, and it doesn't enforce any form of business rule or invariant. It literally only exists to move data around.
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 a bunch of EF decorations all over it's properties, for example, then it I'd argue that it isn't a simple POCO and that it's more in the realm of DAO, which I would describe as a combination of DTO and additional database concerns (e.g. mapping, etc.). POCOs are free and unencumbered like the objects you learn to create in school
这里有一些不同类型的对象模式的例子来比较:
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.
可以将它们仅仅视为对象,但请注意,它们中的大多数通常绑定到一个模式或具有隐含的限制。所以你可以称它们为"对象"或者你可以更具体地描述它的意图,用它是什么来称呼它。这也是为什么我们有设计模式;用几句话描述复杂的概念。DTO是一种模式。聚合根是一个模式,视图模型是一个模式(例如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:
DTO是POCO(直到它被插入) POCO可能不是DTO 视图模型是一个POCO(直到它被仪器化) POCO可能不是视图模型
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, and I'd know that it's ok to put 'hacky' things in there to make sure the data is usable by a UI. 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 and certainly no dependencies on any technical implementation details (databases, services etc.), only abstractions. 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.
历史
转述Fowler的解释:在一个对象很花哨的世界里(例如,遵循特定的模式,有仪器等),它在某种程度上鼓励人们避免使用不花哨的对象来捕获业务逻辑。所以他们给它起了个花哨的名字POJO。如果你想要一个例子,他提到的是“实体Bean”,这是一种具有非常特定的约定和需求的对象。如果你不知道那是什么——> Java Beans。
相比之下,POJO/POCO只是您在学校学习创建的常规ole对象。
其他回答
DTO objects are used to deserialize data into objects from different sources. Those objects are NOT your Model (POCO) objects. You need to transform those objects into your Model (POCO) objects. The transformation is mostly a copy operation. You can fill those POCO objects directly from the source if its an internal source, but its not adviceable if its an external source. External sources have API's with descriptions of the Schema they use. Its much easier then to load the request data in an DTO and after that transform those in your POCO's. Yes its an extra step, but with a reason. The rule is to load the data from your source in an object. It can be JSON, XML whatever. When loaded then transform that data in what you need in your model. So most of times the DTO is an object image of the external source. Sometimes you even get the Schema's of the source providers then you can deserialize even easier, XML works like that with XSD's.
POCO只是一个不依赖于外部框架的对象。这是显而易见的。
POCO是否有行为无关紧要。
DTO可以是POCO,也可以是域对象(通常行为丰富)。
通常dto更可能依赖于外部框架(例如。属性)用于序列化的目的,因为它们通常在系统的边界处退出。
在典型的Onion风格架构中(通常在广泛的DDD方法中使用),领域层被放置在中心,因此它的对象在这一点上不应该有该层之外的依赖关系。
下面是一般规则:DTO=邪恶和过度工程软件的指示器。少= =好。“企业”模式已经摧毁了Java EE世界中许多人的大脑。请不要在。net领域重复这个错误。
DTO的一个主要用例是从web服务返回数据。在这种情况下,POCO和DTO是等价的。POCO中的任何行为在从web服务返回时都将被删除,因此它是否具有行为并不重要。
我认为DTO可以是POCO。DTO更多地是关于对象的使用,而POCO更多地是关于对象的风格(与体系结构概念分离)。
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.
Martin Fowler说这种方法是一条艰难的道路,只有在域层和用户界面之间存在严重不匹配的情况下才应该采用。