In which scenario can I use those design patterns in n-tier architecture?
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 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> cache = new LinkedHashMap>();
public static VO getInstance(int value) {
VO cached = cache.get(value);
if(cached == null) {
cached = new VO(value);
cache.put(value, new WeakReference(cached));
}
return cached.get();
}
private int value;
private VO(int value) {
this.value = value;
}
}