用值对象链接方法

问题描述:

在值对象上使用方法链接模式(比如返回一个新的对象而不是这个)是可以接受/好的做法吗?那里有解决方案实施的案例吗?用值对象链接方法

我想不出任何缺点,但我想听听你的观点。

+0

我提交你的审查,[权威方法链决策树](http://chat.*.com/transcript/message/4316194#4316194) – rdlowrey 2012-08-15 06:31:20

结论:这种做法是完全可以接受的。

我相信这通常是当你有一个不可变的对象时发生的。不是改变原来的对象,而是用给定的值创建一个新的对象并返回。使用方法链接进行和反对的参数与使用可变对象和不可变对象大致相同。

我唯一担心的是,这对于班级的调用者来说很清楚 - 他们不能依赖与链接对象的身份相等性,并且必须明确调用不会改变原始对象。虽然如果他们实际上是串联电话,他们不会分配中介对象,所以不会有很大的风险。重要的是它们只用使用方法链中的最后一个对象。

要使用java.lang.String中作为一个例子,字符串的客户这样做:

myString.trim().replace("a", "b").substring(3, 9); 

...没什么意思,和通常表示程序员的误解。他们应该做的是:

String myNewString = myString.trim().replace("a", "b").substring(3, 9); 

...然后在后续操作中使用myNewString。有趣的是,Java,Findbugs的静态分析工具可以检测到这种误解的实例,并将其报告为可能的错误。

客户理解是主要案例。其他缺点包括,如果价值对象的创建非常昂贵,那么在每条链上创建一个新对象将会带来性能上的冲击。如果这可能是一个问题,你应该能够从你自己的情况中看出来。在这种情况下,您可能需要实现Builder模式,而不是在每个方法链上创建新对象。

除了这些,我想不出任何其他问题。

大量的java类提供了不可变的值对象。 java.lang.String,java.math.BigInteger和java.math.BigDecimal是不可变的值对象,它们的方法返回一个新的对象。最大的缺点是人们对它并不了解,它不可改变,并认为他们正在改变原创。

有些语言比其他语言更强调不变性。在Ruby中,字符串是可变的,并且集合通常提供一个返回副本的版本和另一个改变现有副本的版本(例如Array#sort和Array#sort!)。在Clojure中,不变性是常态。

是的,这是一件非常好的事情。例子:

  • 字符串在Java和.NET
  • DateTimeTimeSpan英寸NET
  • 许多类型中Joda TimeNoda Time
  • 解释功能性的语言,如F#

对于引用类型,其被实现为不可变值对象,其缺点有时会你最终产生了大量的垃圾。在任何一种情况下,您的都可以通过结束大量复制 - 但这取决于具体情况。