ValueObjectsShouldBeImmutable. However, one sometimes has to use a mutable object as a ValueObject. If an object has to use a mutable object as a ValueObject, operations on the mutable value can change the object's internal state without its knowledge and can cause it's state to become inconsistent. For example, altering MartinFowler's example slightly:
public class Task { public void setStartDate( Date d ) { _start_date = d; } ... private Date _start_date; } ... Date d = new Date( some-value ); Task task1; task1.setStartDate( d ); d.setDate( some-other-value );Therefore: an object that holds mutable objects as state must ReturnNewObjectsFromAccessorMethods. Additionally, it must make private copies of mutable objects that are passed to it and that it needs to store internally. For example:
public class Task { public void setStartDate( Date d ) { _start_date = (Date)d.clone(); } ... }-- NatPryce
Except that clone is a bad idea here. If you can be certain that the input parameter is actually a bona fide java.util.Date, you are okay. But if other classes can get into the system, you have a security problem. Consider a BadDate class written as a Date subclass that has its own hook to the outside world. Call the setDtartDate method with it and the insecurity propagates. Better is:
public class Task { public void setStartDate( Date d ) { _start_date = new Date(d.getTime()); } ... }-- EricJablow
Local input parameter modification
// Version 1 function foo(a) { a = modify(a); return process(a); } // Version 2 function foo(a) { var c = a; // make a local copy c = modify(c); return process(c); }Assume that "a" here is passed by value in this dummy language. Would you consider version 1 or version 2 to be the better coding practice? Version 1 is simpler code, but can be misleading if we need to use "a" for other purposes and forget that it's been modified earlier in the function.
Whatever the others working on your project expect. Absent those, I tend to decide based on what semantics I've given the parameter. If it doesn't change the semantics, I tend to use 1. Otherwise, I tend to use 2.