1

I've read a recommendation in "Effective Java" to use the Builder pattern when faced with constructors that use lots of parameters.

Does the same pattern apply to methods with lots of parameters ?

blue-sky
  • 51,962
  • 152
  • 427
  • 752
  • I dont see how to implement a Builder pattern to a method the way the Builder is implemented, I will just consider using Composite and passing null parameters to optional ones – RamonBoza Nov 05 '13 at 16:06
  • 1
    Have you considered using [varargs](http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html)? – Zong Nov 05 '13 at 16:07
  • I see the question as irrelevant. Builder pattern is a creational design pattern and you are talking about methods which are mainly dealt in behavioural design patterns – Abhijith Nagarajan Nov 05 '13 at 16:08
  • You should provide a concrete example/usecase scenario. – tucuxi Nov 05 '13 at 16:13
  • Well, when you create an object holding the parameter values to shorten the parameter list, the applicability of the builder pattern to that parameter object is a natural consequence. – Holger Nov 05 '13 at 16:26

3 Answers3

1

Not exactly, because what Builder does is building an object.

So what would be the point of changing some method, which does who knows what, into a Builder?

What you should do with methods containing too many arguments is for example:

  • break it down to smaller methods,
  • use varargs
  • use some Collection to put into the same type arguments
Eel Lee
  • 3,513
  • 2
  • 31
  • 49
1

Yes, sort of. You basically create a new type to encapsulate all the parameters - or maybe just some of them.

Now you can create a builder and then an immutable version of the type - or you could just allow the "uber-parameter" type to be mutable and pass it directly in. In the latter case you don't have a builder pattern as such, but you can sort of view it as building the method call itself, in that you can specify each aspect of the method call separately. You could argue that the builder pattern is actually just a special case of this pattern, in some ways - it so happens that the build() method is usually on the builder rather than having the builder as a method parameter elsewhere, but there's a definite correlation between the way the two work.

An example of this in the .NET framework is XmlWriterSettings which is passed into a bunch of methods or constructors. (It's sort of used as a builder in that usually it's used when constructing an XmlWriter.) I can't think of any examples within the standard Java library right now, but they may exist somewhere...

If you do find yourself with lots of parameters though, it's worth taking another look at the design to check whether you shouldn't be grouping some of them together anyway, just as part of normal design.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Also, see if you can use an interface to provide the method arguments rather than a concrete type - this will help force what you actually need in the method to come to the forefront (objects that contain that information often will have other properties and methods you don't need, such as setters when you only need getters, etc). – MetroidFan2002 Nov 05 '13 at 16:13
  • @MetroidFan2002: Hmm... if I were designing a type specifically for a method call, I wouldn't want to reuse the existing classes anyway, I suspect. It may be appropriate in some cases, but I don't think I've used that pattern myself. – Jon Skeet Nov 05 '13 at 16:14
  • @Jon_Skeet Sometimes in implementation it's pretty easy to make an object that decorates related ones with the appropriate information once you've fleshed out your interface - it all depends on your model, of course. – MetroidFan2002 Nov 06 '13 at 14:58
1

Turning a method into a builder is possible but atypical. Apache HashCodeBuilder is one example, used like int hash = new HashCodeBuilder().append(a).append(b).build();, although in that specific case you might prefer to just use a method with varargs, like Guava's Objects.hashCode, used like int hash = Objects.hashCode(a, b);.

A method which takes a large number of arguments of different types is ill-suited to varargs, so you might find a builder appropriate, or you might want to consider reducing the amount of work that is being done in that method, or encapsulating the arguments in some other composite type.

MikeFHay
  • 8,562
  • 4
  • 31
  • 52