Reputation: 116522
When creating classes for "immutable objects" immutable meaning that state of instances can not be changed; all fields assigned in constructor) in Java (and similar languages), it is sometimes useful to still allow creation of modified instances. That is, using an instance as base, and creating a new instance that differs by just one property value; other values coming from the base instance. To give a simple example, one could have class like:
public class Circle {
final double x, y; // location
final double radius;
public Circle(double x, double y, double r) {
this.x = x;
this.y = y;
this.r = r;
}
// method for creating a new instance, moved in x-axis by specified amount
public Circle withOffset(double deltaX) {
return new Circle(x+deltaX, y, radius);
}
}
So: what should method "withOffset" be called? (note: NOT what its name ought to be -- but what is this class of methods called). Technically it is kind of a factory method, but somehow that does not seem quite right to me, since often factories are just given basic properties (and are either static methods, or are not members of the result type but factory type).
So I am guessing there should be a better term for such methods. Since these methods can be used to implement "fluent interface", maybe they could be "fluent factory methods"? Better suggestions?
EDIT: as suggested by one of answers, java.math.BigDecimal
is a good example with its 'add', 'subtract' (etc) methods.
Also: I noticed that there's this question (by Jon Skeet no less) that is sort of related (although it asks about specific name for method)
EDIT, MAY-2014: My current favorite is mutant factory
, FWIW.
Upvotes: 5
Views: 1745
Reputation: 87543
I call those types of methods "copy methods".
While the clone()
method creates an exact copy, a copy method makes a copy of an instance, usually with an implied or explicit variation. For example, String#toUpperCase()
would be a copy method of the immutable String class - it copies an instance with a variation: it upcases all the letters.
I would consider withOffset()
method in your example to be a similar copy method.
I don't know of any references that document the term "copy method". I'm borrowing the term "copy" from its use in C++: copy constructors and the "copy" naming guideline from the Taligent Coding Standards (more info).
As for the term "fluent factory methods", I don't know why "fluent" would make a difference, since a "fluent interface" is just an API style (separate from the builder pattern). If the term "factory method" doesn't apply here, I don't see how calling it a "fluent factory method" makes it apply any better.
Upvotes: 3
Reputation: 8245
Hrm … it creates mutated versions of the object … maybe we should call it a mutant factory? :-)
Upvotes: 3
Reputation: 38205
This does not really look like a factory method. The signature alone only tells me that I can chain it in different calls, but not that it is supposed to create a new instance: I see this use case more like a StringBuilder that allows append("a").append("b"). It could, of course return a new StringBuilder every time (as your Circle does).
So it's not by design a factory. (Think of extracting the interface and writing the JavaDoc for that method: "one must return a new instance, since I'm immutable" -- why so ??) The fact that your class is immutable is just an implementation detail).
EDIT: Perahs a better example would be BigInteger, since that's also immutable. Along with multiply(BigInteger), it provides a package-private method:
BigInteger multiply(long v)
which returns a new instance and resembles your case very well. That's simply an operation that happens to return a result of the same type as the initial object; not a factory and I don't think this kind of operation really deserves its own name.
Upvotes: 1