Difference between Value Object pattern and Data Transfer pattern

19,640

Solution 1

DTO is the object that you can use at the boundaries of the system. When you have a SOAP web service for example and you want to return response you would use DTO. It easier to deal with than actual XML that has to be returned over the wire. DTOs are often generated by tools, based on WSDL for example. DTO are often tailored to the needs of service consumer and can be affected by performance requirements.

Value objects on the other hand live in the core of the system. It captures pieces of business logic and maybe formatting rules. It makes your code more type safe and expressive. It also tackles "Primitive obsession" anti pattern. Good example is using class "SocialSecurityNumber" instead of string. Or Money instead of decimal. These objects should be immutable so that they look more like primitives and can be easily shared among different threads.

For example in hypothetical 'customer-order' system:

CustomerAndLastFiveOrders is DTO (optimized to avoid multiple network calls)

Customer is Entity

Money and SKU are Value objects

Solution 2

Comparing DTO objects with value objects is like comparing oranges and apples.

They serve completely different situations. DTO defines the object / class structure of how data will be transferred between layers while value objects defines the logic for equality when values are compared.

enter image description here

Let me explain you with examples, let us first try to understand value objects first :-

Value object is an object whose equality is based on the value rather than identity.

Consider the below code we have created two objects of money one is one rupee coin and the other is a one rupee paper currency.

Money OneRupeeCoin = new Money();
OneRupeeCoin.Value = 1;
OneRupeeCoin.CurrencyType = "INR";
OneRupeeNote.Material = "Coin";

Money OneRupeeNote = new Money();
OneRupeeNote.Value = 1;
OneRupeeCoin.CurrencyType = "INR";
OneRupeeNote.Material = "Paper";

Now when you compare the above objects the below comparison should evaluate to true because 1 rupee note is equal to 1 rupee coin in real world.

So either you are using “==” operator or you are using the “Equals” method the comparison should evaluate to true. By default “==” or “equals” will not evaluate to true so you need to use operator overriding and method overriding to get the desired behavior. You can see this link which explains how to achieve the same.

if (OneRupeeCoin==OneRupeeNote)
 {
 Console.WriteLine("They should be equal");
 }
if (OneRupeeCoin.Equals(OneRupeeNote))
 {
 Console.WriteLine("They should be equal ");
 }

Normally value objects are good candidates for immutability; you can read more about it from here. You can see this video which describes how immutable objects can be created.

Now let’s try to understand DTO:-

DTO (Data Transfer objects) is a data container for moving simplifying data transfer between layers.

They are also termed as transfer objects. DTO is only used to pass data and does not contain any business logic. They only have simple setters and getters.

For example consider the below call we are making two calls one to get customer data and the other to get product data.

DataAccessLayer dal = new DataAccessLayer();
//Call 1:-  get Customer data
CustomerBO cust = dal.getCustomer(1001);

//Call 2:-  get Products for the customer
ProductsBO prod = dal.getProduct(100);

So we can combine the Customer and Product class in to one class as shown below.

class CustomerProductDTO
{
  // Customer properties
        public string CustomerName { get; set; }
   // Product properties
        public string ProductName { get; set; }
        public double ProductCost { get; set; }
}

Now with one call we will be able to get both customer and product data. Data transfer objects are used in two scenarios one to improve remote calls and second to flatten object hierarchy; you can read this article which explains more about data transfer objects.

//Only one call
CustomerProductDTO cust = dal.getCustomer(1001);

Below is the complete comparison sheet.

enter image description here

Solution 3

There are several good answers here, but I'll add one to capture a key difference:

Value objects do not have an identity. That is, any comparison between two instances of a value object that contain the same values should indicate that they are equal. Data Transfer Objects, while only being used to hold values, do have an identity. Comparing two instances of a DTO that have the same values, but were created independently, will not indicate that they are equal.

Example:

DTO dto1 = new DTO(10);
DTO dto2 = new DTO(10);
dto1.equals(dto2); //False (if equals is not overridden)
dto1 == dto2; //False

VO vo1 = VO.getInstance(10);
VO vo2 = VO.getInstance(10);
vo1.equals(vo2); //True
vo1 == vo2; //True

It's slightly difficult to implement the Value Object pattern in Java, since the == operator always compares object identity. One way to do so would be to implement an object cache that returns the same object for each value.

public class VO {
  Map<Integer, WeakReference<VO>> cache = new LinkedHashMap<Integer, WeakReference<VO>>(); 
  public static VO getInstance(int value) {
     VO cached = cache.get(value);
     if(cached == null) {
        cached = new VO(value);
        cache.put(value, new WeakReference<VO>(cached));
     }
     return cached.get();
  }

  private int value;
  private VO(int value) {
    this.value = value;
  }
}

Solution 4

A value object is something that is useful to encapsulate as an object, but it has no identity. Compare it to an entity, which is something that does have identity. So in an order-processing system a Customer or an Order or a LineItem are concepts that point back to specific people or things or events, so they are entities, where a value object is something like a monetary amount, that doesn't have an independent existence of its own. For instance, for a system where part of the application involved calculating how to divide a payment between different accounts, I created an immutable Money object that had a divide method that returned an array of Money objects evenly splitting the original object's amount across them, that way the code for dividing amounts was in a place that was handy where the person writing the jsp could use it, and they didn't have to mess up the jsp with non-presentation-related code.

A Data Transfer Object is a wrapper for bundling things together for sending across application tiers or layers. The idea is that you want to minimize the amount of network back-and-forth traffic by designing methods that send large bundles of information.

Solution 5

I would advise against the data transfer object. It's an EJB 1.0 anti-pattern, in my opinion, given value by those who insist in layer purity.

A value object is useful. It's usually an immutable object, like Money. They should be thread-safe.

Share:
19,640
Admin
Author by

Admin

Updated on June 27, 2022

Comments

  • Admin
    Admin about 2 years

    In which scenario can I use those design patterns in n-tier architecture?

  • Bhesh Gurung
    Bhesh Gurung almost 13 years
    Sorry. I thought you said that we have to make it thread safe.
  • Luchostein
    Luchostein over 8 years
    Sometimes, a DTO works as an (network an serialization) optimization because your business object can be quite heavy, but you only need to transfer a small fraction of its information.
  • Pang
    Pang over 5 years
    "any comparison between two instances of a value object that contain should indicate that..." - "that contain"? Contain what?
  • ThomasH
    ThomasH about 3 years
    @Pang Fixed the sentence.