I have a java project that involves building some pretty complex objects. There are quite a lot (dozens) of different ones and some of them have a HUGE number of parameters. They also need to be immutable.
So I was thinking the builder pattern would work, but it ends up require a lot of boilerplate. Another potential solution I thought of was to make a mutable class, but give it a "frozen" flag, a-la ruby.
Here is a simple example:
public class EqualRule extends Rule {
private boolean frozen;
private int target;
public EqualRule() {
frozen = false;
}
public void setTarget(int i) {
if (frozen)
throw new IllegalStateException(
"Can't change frozen rule.");
target = i;
}
public int getTarget() {
return target;
}
public void freeze() {
frozen = true;
}
@Override
public boolean checkRule(int i) {
return (target == i);
}
}
and "Rule" is just an abstract class that has an abstract "checkRule" method.
This cuts way down on the number of objects I need to write, while also giving me an object that becomes immutable for all intents and purposes. This kind of act like the object was its own Builder... But not quite.
I'm not too excited, however, about having an immutable being disguised as a bean however.
So I had two questions: 1. Before I go too far down this path, are there any huge problems that anyone sees right off the bat? For what it's worth, it is planned that this behavior will be well documented... 2. If so, is there a better solution?
Thanks
Foo().setBar(5).addBaz(1).addBaz(2).build()
. Upon the finalbuild()
call, the builder object returns an immutable implementation of Foo, which can as well be the builder itself in frozen state.return this
is another pattern, called fluid interface; to me it seems very convenient. One of the nice things about it is that a "setter" becomes a "modifier" that can return a different object (notthis
) is a particular step allows for a different, optimized representation.