Functional setter Java idiom

The way of organizing the code I will show in this post is very common, but, perhaps, it's useful to give it a name, and I will call it the "functional setter java idiom". Let's see.

In java there are no named parameters, i.e. parameters that I can pass to a method in the order I like calling them with their name. For example in Visual Basic for Applications we can sort some Excel cells this way:

 
SelectedSheets.PrintOut Copies:=1, _
    Preview:=True, _
    PrintToFile:=True, _
    Collate:= True
 

Note that the order in which I set the parameters is arbitrary, and that some parameters can be omitted, having it assigned with default values.

Now let's suppose we need to create an object with a long series of parameters (OK, I know, it's a code smell, but, please, close your nose for a while):

 
PrintType printType = new PrintType(1, true, true, true);
 

Well, not a good piece of code! Especially the sequence of boolean parameters is a mess. Moreover, sometimes I'd like to create my object with less parameters, having the others set with default values. I could create many constructors, but this would increase the complexity of my program.

I could solve the problem using some setters:

 
PrintType printType = new PrintType();
printType.setCopies(1);
printType.setPreview(true);
printType.setPrintToFile(true);
printType.setCollate(true);
 

Uhmm, better enough, but what if I need to assign my object to a constant, i.e. a final static field? I should write:

 
public final static PrintType DEFAULT_PRINT = new PrintType();
 
static {
	DEFAULT_PRINT.setCopies(1);
	DEFAULT_PRINT.setPreview(true);
	DEFAULT_PRINT.setPrintToFile(true);
	DEFAULT_PRINT.setCollate(true);
}
 

Mamma mia, this code is ugly! Maybe I could improve it just a bit using some functional setters, i.e. setters that have a return value, as a function. In the PrintType class I should write:

 
public PrintType setCopies(int copies) {
	this.copies = copies;
	return this;
}
 
public PrintType setPreview(boolean value) {
	this.preview = value;
	return this;
}
 
public PrintType setPrintToFile(boolean value) {
	this.printToFile = value;
	return this;
}
 
public PrintType setCollate(boolean value) {
	this.collate = value;
	return this;
}
 

Now the initialization of my static field becomes:

 
public final static PrintType DEFAULT_PRINT = new PrintType()
	.setCopies(1)
	.setPreview(true)
	.setPrintToFile(true)
	.setCollate(true);
 

This is not so bad, don't you think?

5 commenti

  1. gabriele renzi:

    I believe this is what is usually called a fulent interface http://en.wikipedia.org/wiki/Fluent_interface
    And yes, it is a nice idea :)

  2. Franco Lombardo:

    Oh, good pointer Gabriele: I need to read more next time! :-)

  3. alepuzio:

    Hi,
    It’a good systems: the only problem, in my opinion, is that some framwork (as Struts) work with the hypothesis that the developer is coding with JavaBean’s standards ( void setAttribute(XXX xxx) ).
    Coding in Fluent Interface’s way, dont you break this hypothesis ?

    Bye

  4. Franco Lombardo:

    @alepuzio

    There is no problem, because I don’t use Struts :-)
    More seriously, obviously in this particular case, fluent interfaces (or functional setters as I love to call them :-) ) are just setters that return the object itself, so I think they should work even with Struts.
    Anyway, fluent interfaces are intended to develop in a DSL-like manner, not in the “old JavaBeans” standard.

  5. alepuzio:

    I agree, then do you think that the change of “convention” not create problems in web apps “old style”? :)

    My doubt is about the manutenibility when you code from “JavaBean world” to “Fluent Interface world”

    >DSL-like manner
    It’s better ;)

Lascia un commento

You must be logged in to post a comment.