DTO vs Value Object vs POCO

In this article, I’d like to clarify the differences in DTO vs Value Object vs POCO where DTO stands for Data Transfer Object, and POCO is Plain Old CLR Object, also known as POJO in Java environment.

DTO vs Value Object vs POCO: definitions

First of all, I want to make a note regarding Value Object. There’s a similar concept in C#, namely Value Type. It’s just an implementation detail of how objects are being stored in memory and I’m not going to touch this. Value Object, which I’m going to discuss is a DDD concept. Check out this article to read more about it.

Alright, let’s start.

You might have noticed that such notions as DTO, Value Object and POCO are often used interchangeably. But are they really synonyms?

DTO is a class representing some data with no logic in it. DTO’s are usually used for transferring data between different applications or different layers within a single application. You can look at them as dumb bags of information the sole purpose of which is to just get this information to a recipient.

On the other hand, Value Object is a full member of your domain model. It conforms to the same rules as Entity. The only difference between Value Object and Entity is that Value Object doesn’t have its own identity. It means that two Value Objects with the same property set should be considered the same whereas two Entities differ even if their properties match.

Value Objects do contain logic and, typically, they are not used for transferring data between application boundaries.

POCO (Plain Old CLR Object) is a term created as an analogy for POJO only because “POJO” itself can’t be used in .NET as the letter “J” in it stands for “Java”. Thus, POCO has the same semantics as POJO.

POJO was introduced by Martin Fowler and others to oppose JavaBeans and other heavy-weight enterprise constructions that gained a lot of popularity back in early 2000’s.

The primary goal of POJO is to show that domain can be successfully modeled without bringing to the table complexity related to the execution environment (and JavaBeans brought a lot of it in its early versions). Moreover, the execution environment shouldn’t have anything to do with domain modeling at all.

There’s no direct analogy for JavaBeans in .NET because Microsoft has never introduced the same concept, but we can come up with some made up parallel to help express this concept.

You can think of Component class from System.ComponentModel namespace as an opposite for POCO. There are a lot of classes in .NET that inherit from Component, for example, DBCommand from System.Data and EventLog from System.Diagnostics.

Of course, in most cases, you wouldn’t create a domain class inheriting from Component. It just doesn’t make any sense, because such approach brings a lot of unnecessary complexity, thus contradicting the YAGNI principle.

Another good example of non-POCO approach is Entity Framework before 4.0 version. Every class EF generated inherited from EntityObject base class and thus brought a lot of complexity specific to Entity Framework. Since version 4.0, Entity Framework introduced POCO data model which allows for use of classes that don’t inherit from EntityObject.

That said, POCO stands for use of as simple classes as possible for domain objects. This notion helps conform to YAGNI, KISS and other best practices. POCO classes can contain logic.

DTO vs Value Object vs POCO: correlations

Are there any connections between these terms? There are a few.

First of all, DTO and Value Object represent different concepts and can’t be used interchangeably. On the other hand, POCO is a superset for DTO and Value Object:

Relationship between DTO, Value Object, and POCO

Relationship between DTO, Value Object, and POCO

In other words, Value Object and DTO shouldn’t inherit any heavy-weight enterprise components and thus they are POCO. At the same time, POCO is a wider set: it can be Value Object, Entity, DTO or any other class you might create as long as it doesn’t inherit complexity accidental to your domain.

Here are properties for each of them:

Properties of DTO, Value Object, and POCO

Properties of DTO, Value Object, and POCO

Note that POCO may both have and not have its own identity. It depends on what type of POCO it is: Value Object or Entity. Also, POCO may or may not contain logic in it. It depends on weather or not POCO is DTO.


Alright, I hope I made it at least a little bit clearer. I’d like to summarize this topic with the following:

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

  • http://www.thecloudeveloper.com Lincoln Pires

    Hello Vladimir, how are you doing?

    Man, your post is pure and simple as possible and explains things very well!
    Direct to the point and with many forms to remember the concepts you explained.
    Very good post.

    This blog is now on my “follow” folder of favorites / bookmarks.

    Greetings from Brazil.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thanks Lincoln, that is very kind from of you to say that!
      Really appreciate you liked that, I tried to distil it as much as I could.

  • Birama

    very nice post. Good job and great information. Thanks from Senegal.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thank you!

  • Sabarinathan Arthanari

    Very Good explanation. Nicely sums up. If small note is added, It will be more helpful. As Martin explains if POCO is used for business layer, It must have business logic. Otherwise it will lead to an AnemicDomainModel http://www.martinfowler.com/bliki/AnemicDomainModel.html

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Good point. Thanks!

  • Alexey Pakseykin

    Just a comment for correctness…

    You would want to replace “JavaBeans” with “EJB2” in all 3 paragraphs where `JavaBean` is mentioned. JavaBean is almost as plain as simple POJO – it only requires three properties: default constructor, serializable, getter/setter. At the same time EJB2 neither builds upon nor extends the original JavaBean specification (they are unrelated). And why “2” in “EJB2”? Because only EJB2 were actually heavily bound to the Java EE (rather than being plain business logic components), and recent releases of EJB specification (EJB3+) allow POJOs to be used for the same purpose.

    So, in short, neither “JavaBean” fit the surrounding text nor “EJB” in general – only “EJB2” seems the solution for the “puzzle” to make the paragraphs sound right.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      I’m no expert in Java or JVM, so feedback from a Java specialist is much appreciated. Changed “JavaBeans” to “EJB2”, thanks!

      • Alexey Pakseykin

        My bad… I didn’t take the effort to construct the text and see how it reads after changes in all cases. And while the main point of changes is not missed, the middle paragraph sounds wrong on specific detail:

        “The primary goal of POJO is to show that domain can be successfully modelled by classes that don’t _inherit_ from EJB2, and, moreover, EJB2 _shouldn’t_ be used for domain modelling at all.”

        Let me put it the right way (feel free to rewrite it your way):

        “The primary goal of POJO is to show that domain can be successfully modelled by classes that are free of code related to execution environment (as legacy EJB2 were compared to recent versions of the specification), and, moreover, the execution environment shouldn’t have anything to do with domain modelling at all.”

        The difference (as you can see) is the fact that nothing tend to “inherit from EJB2” – instead, EJB2 had to implement (undesired) code related to execution environment in addition to the desired code to model domain. In other words, EJB2 (like any EJB since day 1) are actually meant to model the domain.

        In the context of your article with just this one detail (what was POJO and what was not), my comment can be trusted. But I’m also late in Java EE field and haven’t met (legacy) EJB2 – not an expert on history. I have only seen multiple comparisons in articles, books, blogs and so on – e.g. the easiest to quote:
        “EJB 3.0 performs better because it uses POJOs… EJB 2.0 does not implement POJO.”

        Thanks for attention!

        And just a thought while writing this comment… It is obviously impossible to be completely detached from execution environment (ultimately, choice of programming language binds to some details of execution environment). Nevertheless, expressing these aspects declaratively (like in-code annotations or external configuration in EJB3 compared to some container-related implementation like in EJB2) makes model clear.

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Ah, I see, so there aren’t any inheritance, but rather some implicit interface implementation. Updated the article, let me know if you see anything to correct in this version.

          Regarding the complete detachment from the execution environment – indeed! The ToString() and GetHashCode() methods show that no class is actually a POJO/POCO in its purest form. Rather, we have a purity spectrum here.

  • http://www.bravohex.com/ Bravo Hex

    Thanks Vladimir, It’s very helpful for me!

  • Gemma B

    Thanks for your article. I don’t work with Java so the POJO went over my head a little. I picked up what you said about value objects not being used for transferring data through the application.

    Would it be silly to use value objects within dtos. I wanted to use a ProductDTO in my trivial application, setting a price variable as a monetary value. The moment I query my database, I know my price is set in decimal £15.99. However, for another external api, the value is represented in coin value, cents/pence 1599p. Would it be wrong to ensure the type of data my dto is carrying is one my domain model can use.

    Don’t kill me because of my php example:

    public function setPrice(MoneyAsDecimal $price) {
    $this->price = $price;

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      In simple domains, it’s not that important to distinguish between POJOs and DTOs. However, in more complex ones (or if you want to practice your DDD skills), I’d recommend you do explicit conversion between the two. Whenever you use a value inside the domain model, convert it into a Value Object. And whenever this value goes outside of the said model, convert it into a POJO.

  • Phil

    I’ve been trying to understand the need to separate a DTO from the object containing behaviour. In C++ a class:

    class MyThing
    { int a; Inc() {a++;} }

    is 4 bytes (or whatever the int size is). If you don’t have a virtual method somewhere then the object is just the data members.

    While in Java and C# I think it comes loaded with a vptr and other potential inherited stuff.

    Is this the reason why DTOs exist at all?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      There are mostly 2 reasons (maybe more but these 2 are the ones that come to mind right now):

      1) They serve as containers to transfer data between layers. It’s OK to use regular domain classes in simple cases. In complex scenarios, however, you often need to shape that data differently and the existing domain classes may not fit this shape well.

      2) They represent data contracts between applications. Once published, data contracts are hard to change because of backward compatibility issues, so it’s often a requirement to keep the shape of the data unchanged. DTOs help decouple the domain model from those data contracts. You can freely change the domain model as along as you keep the DTOs unmodified, changing only mappings between them.

      • Phil

        Thanks for you quick response.

        Point 2) makes a lot of sense to me.

        Point 1) I’ll have to think about a bit more.

  • http://www.alireza-rahmani.ir/ alireza Rahmani khalili

    Thanks for great post, In dto can we have some behaviour, for example I want to send product to upper layer and in the dto can I call currency converter for each product price?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      I wouldn’t recommend doing this. Look at DTOs as pure data containers, nothing else. Attribute any logic upon them to app services.

  • http://www.alireza-rahmani.ir/ alireza Rahmani khalili

    what is your idea about serialising instead of dto? I saw some ddd implementation someone use serialiser instead of dto.

  • 3amprogrammer

    Does value object have to contain logic? Can we have value object without logic?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      It sure can. Baking logic in is the whole reason for creating a VO, though, so a VO without any logic is probably not worth the additional class. Note that validation is also a part of business logic, so a VO with just validation rules is also fine.

  • Zafer Balkan

    I have followed a really bad practice for the needs in a legacy domain model due to laziness. I have a BaseObject that every class (no matter DTO or VO) inherits. The class overrides ToString() method with a sorted JSON creator. It implements IEquatable, by comparing the values of ToString(). The class benefits from a public Guid ID property created on constructor but not included in JSON creation, so that the value is not affected. So if I want to use any object as a VO I use the overridden Equals method and operators. If I want to use as a DTO I can use the ID or use ReferenceEquals() method. Yeah, this is some kind of monstrosity.

  • http://barname-nevis.com Mohammad

    Thanks for your great post.
    Can DTO classes contain attributes for serialization or something else like [Required] in “System.ComponentModel.DataAnnotations” namespace?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      When it comes to POCO, there are various degrees of purity. In DTOs, especially incoming DTOs, validation and serialization attributes are fine. I don’t recommend using those attributes in Value Objects or Entities.

      • http://barname-nevis.com Mohammad

        I usually use attributes in my entity classes, like [Required] and [ForeignKey]. I find it more readable than using fluent API configurations.

        But you are suggesting that using fluent API is a better approach. am I correct or I am missing something here?

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          No I’m actually suggesting that attributes may be fine if used for validation. Note that it’s not entities but specifically DTOs where they are fine. DTOs (data contracts) != domain entities.

          • http://barname-nevis.com Mohammad

            Actually, my second question was about the domain entities to be used for entity framework which I found using fluent API is the only way to properly separate the application layer (including domain entities) from database logic.
            Thanks, your answers were very helpful 😉