In this article, I would like to clarify the differences between the DTO (Data Transfer Object), Value Object and POCO (Plain Old CLR Object), also known as POJO in Java.
DTO, POCO and Value Object Definitions
Initially, a small remark about the Value Object. In C #, there is a similar concept called Value Type. This is just a detail of the implementation of how objects are stored in memory and we will not touch this. The Value Object in question is a pull from the DDD (Domain-Driven Design) environment.
OK, let's get started. You may have noticed that concepts like DTO, Value Object, and POCO are often used interchangeably. But do they really mean the same thing?
DTO is a class containing data without any logic to work with them. DTOs are usually used to transfer data between different applications, or between layers within the same application. They can be considered as a repository of information, the sole purpose of which is to transmit this information to the recipient.
')
On the other hand, the Value Object is a full member of your domain model. It follows the same rules as entities. The only difference between the
Value Object and the
Entity is that the Value Object does not have its own identity. This means that two Value Objects with the same properties can be considered identical, while the two entities differ from each other even if their properties completely coincide.
Value Objects
can contain logic and are usually not used to transfer information between applications.
POCO (Plain Old CLR Object) is a term created by analogy for POJO. POJO cannot be used in .NET due to the fact that the letter “J” in it means “Java”. POCO has the same semantics as POJO.
POJO was introduced by Martin Fowler as an alternative to JavaBeans and other “heavy” enterprise designs that were popular in the early 2000s.
POJO’s main goal was to show that the application domain can be successfully modeled without using JavaBeans. Moreover, JavaBeans should not be used for this purpose at all.
In the .NET environment, there is no direct analogy for JavaBeans, since Microsoft has never imagined anything like it, but we can come up with some parallel.
You can think of the
Component class from System.ComponentModel as the opposite of POCO. In .NET, there are many classes that inherit from Component, for example, the DBCommand from System.Data or the EventLog from System.Diagnostics.
Inherit domain classes from Component in most cases does not make any sense, because This solution adds unnecessary complexity to the model. Using heavyweight classes from the .NET Framework for such purposes is contrary to the principle of
YAGNI .
Another good example of the anti-POCO approach is the Entity Framework prior to version 4.0. Each class generated by EF inherits from EntityObject, which introduces EF-specific logic to the domain. Starting with version 4, the Entity Framework added the ability to work with the POCO model — the ability to use classes that are not inherited from EntityObject.
Thus, the
concept of POCO means using as simple classes as possible to model the domain . This concept helps to adhere to the principles of YAGNI,
KISS and other best practices.
POCO classes may contain logic .
Correlation between concepts
Are there any connections between these three concepts? First of all, DTO and Value Object reflect different concepts and cannot be used interchangeably. On the other hand, POCO is a superset for DTO and Value Object:

In other words, the Value Object and DTO do not inherit any third-party components and thus are POCO. At the same time, POCO is a broader concept: it can be a Value Object, Entity, DTO, or any other class if it does not inherit components that are not directly related to the problem you are solving.
Here are the properties of each of them:

Note that a POCO class may or may not have its own identity, since it can be either a Value Object or an Entity. Also, a POCO may or may not contain logic within itself. It depends on whether the POCO DTO is.
Conclusion
The above can be summarized as follows:
- DTO! = Value Object
- DTO ⊂ POCO
- Value Object ⊂ POCO
English version of the article:
DTO vs Value Object vs POCO