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

我想不出有什么缺点,但我想听听你的观点。

有帮助吗?

解决方案

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

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

我会唯一要担心的是,这是明确的类的调用者 - 他们可以不依赖于与链接的对象的身份平等,它必须明确的呼叫没有改变原来的对象。尽管如果他们实际上链接的电话,他们不会被分配的中间对象,所以不会有太多的这样的风险。最重要的是,他们的只有的使用的最后一个对象的方法链。

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

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

...意味着什么,并且一般表示程序员误解。他们的的做是这样的:

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

...,然后用在随后的操作myNewString。有趣的是,为Java,FindBugs的,静态分析工具可以检测到这种误解的情况,并将其报告为可能的错误。

客户端的理解是主壳体。其他缺点包括:如果值对象是非常昂贵的创建,使每条链上的一个新的将是一个性能命中。您应该能够从自己的情况说,如果这有可能是一个问题。在这种情况下,而不是创建每个方法链一个新对象时,可能需要实施生成器模式。

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

其他提示

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

  • Java 和 .NET 中的字符串
  • DateTimeTimeSpan 在.NET中
  • 多种类型在 乔达时间野田时间
  • 函数式语言(例如 F#)中的列表

对于作为不可变值对象实现的引用类型,缺点有时可能是最终生成大量垃圾。无论哪种情况你 最终会进行大量的复制——但这取决于具体情况。

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

有些语言强调有恒比别人多。在Ruby中的字符串是可变的,和集合通常提供一个版本,返回一个副本,另一个变异现有副本(例如阵列#排序和阵列#排序!)。 Clojure中不变性是常态。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top