用值对象链接的方法

时间:2009-12-30 18:48:21

标签: design-patterns method-chaining value-objects

在值对象上使用方法链接模式是否可接受/良好实践(比如,返回一个新对象而不是这个)?是否存在实施此解决方案的案例?

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

3 个答案:

答案 0 :(得分:5)

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

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

我唯一担心的是这对于类的调用者来说是明确的 - 他们不能依赖于与链接对象的身份相等性,并且必须明确调用不会改变原始对象。虽然如果它们实际上是在联系呼叫,但它们不会分配中间对象,因此不会有太大的风险。重要的是,他们使用方法链中的最后一个对象。

以java.lang.String为例,String的客户端执行此操作:

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

...没有任何意义,通常表示程序员误解。他们应该做的是:

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

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

客户理解是主要案例。其他缺点包括如果值对象创建起来非常昂贵,那么在每个链上创建一个新对象将会受到性能影响。您应该能够从自己的场景中判断出这可能是一个问题。在这种情况下,您可能希望实现Builder模式,而不是在每个方法链上创建新对象。

除此之外,我想不出任何其他问题。

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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

  • Java和.NET中的字符串
  • DateTime和.NET中的TimeSpan
  • Joda TimeNoda Time
  • 中的多种类型
  • 以F#
  • 等功能语言列出

对于作为不可变值对象实现的引用类型,有时可能会导致最终产生大量垃圾。在任何一种情况下,都可以最终进行大量复制 - 但这取决于具体情况。