views:

220

answers:

3

is it acceptable/good-practice to use the method chaining pattern on value objects (like, returning a new object instead of this)? are there cases out there where this solution is implemented ?

I cannot think of any drawbacks, but I'd like to hear your point.

+2  A: 

Lots of java classes provide immutable value objects. java.lang.String, java.math.BigInteger, and java.math.BigDecimal are immutable value objects, their methods return a new object. The biggest drawback with it is people new to it don't understand it's immutable and think they're changing the original.

Some languages emphasize immutability more than others. In Ruby strings are mutable, and collections often provide a version that returns a copy and another that mutates the existing copy (for instance Array#sort and Array#sort!). In Clojure immutability is the norm.

Nathan Hughes
+4  A: 

Conclusion: this practice is completely acceptable.

I believe this is generally what occurs when you have an immutable object. Instead of mutating the original object, a new one is created with the given value and returned. The arguments for and against doing this with method chaining are roughly the same as using mutable vs. immutable objects.

The only concern I would have is that this is made clear to the callers of the class - they cannot depend on identity equality with the chained object and it must be made clear the call is not changing the original object. Although if they were actually chaining the calls, they would not be assigning the intermediary objects, so there wouldn't be much of a risk of this. What's important is that they only use the last object in the method chain.

To use java.lang.String as an example, a client of String doing this:

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

... means nothing, and generally indicates programmer misunderstanding. What they should be doing is this:

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

... and then using myNewString in subsequent operations. Interestingly, the static analysis tool for Java, Findbugs, can detect instances of this misunderstanding, and report it as a probable bug.

Client understanding is the main case. Other drawbacks include if the value object is very expensive to create, making a new one on each chain will be a performance hit. You should be able to tell from your own scenario if this is likely to be an issue. In this case, rather than creating a new object on each method chain, you may want to implement the Builder Pattern.

Apart from those, I can't think of any other issues.

Grundlefleck
+2  A: 

Yes, this is a perfectly good thing to do. Examples:

  • String in Java and .NET
  • DateTime and TimeSpan in .NET
  • Many types in Joda Time and Noda Time
  • Lists in functional languages such as F#

For reference types which are implemented as immutable value objects, the drawback can sometimes be that you end up generating a lot of garbage. In either case you can end up with a lot of copying going on - it depends on the exact situation though.

Jon Skeet