状态封装在可变对象中的对象通常不应向外界公开对该对象的任何引用,并且应避免向外界提供对声称封装其状态的任何可变对象(甚至是副本)的引用。问题是给定的代码:
Foo foo = myEntity1.getFoo();
foo.bar = 23;
myEntity2.setFoo(foo);
foo.bar = 47;
myEntity3.setFoo(foo);
没有明确的迹象表明更改是否或如何foo.bar
影响各个实体。如果代码改为:
Foo foo = myEntity1.getFoo();
foo = foo.withBar(23); // makes a new instance which is like foo, but where bar==23
myEntity2.setFoo(foo);
foo = foo.withBar(47); // makes a new instance which is like foo, but where bar==47
myEntity3.setFoo(foo);
很明显's的bar
属性不受影响,of的属性为23, of 的属性为47。如果是可变类,则模式应为:myEntity1
foo
myEntity2
myEntity3
foo
Foo foo = new Foo();
myEntity1.writeTo(foo); // Copy properties from myEntity1 to the supplied instance
foo.bar = 23;
myEntity2.readFrom(foo); // Copy properties from the supplied instance to myEntity2
foo.bar = 47;
myEntity2.readFrom(foo); // Copy properties from the supplied instance to myEntity3
在这里,myEntity1
不是给调用者一个对象,而是将数据复制到调用者提供的对象中。因此,调用者不应期望写入foo.bar
直接影响实体,而只是更改将在后续readFrom
调用中写入的内容,这一点就更清楚了。