【问题标题】:Method chaining with value objects使用值对象链接方法
【发布时间】:2009-12-30 18:48:20
【问题描述】:

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

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

【问题讨论】:

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


【解决方案1】:

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

我相信这通常是当你有一个不可变对象时发生的。不是改变原始对象,而是使用给定值创建一个新对象并返回。支持和反对使用方法链接执行此操作的论点与使用可变对象与不可变对象大致相同。

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

以 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 模式,而不是在每个方法链上创建一个新对象。

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

【讨论】:

    【解决方案2】:

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

    • Java 和 .NET 中的字符串
    • .NET 中的DateTimeTimeSpan
    • Joda TimeNoda Time 中的许多类型
    • 函数式语言(例如 F#)的列表

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-09
        • 2013-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-13
        • 2015-01-15
        相关资源
        最近更新 更多