5

Java 1.6

I have a method with many parameters. This is not a constructor but a normal method.

 class A {
   public void m (int a, int b, boolean c, List<>...) { }
 }

How to replace a method to a better form ? As I understand the Builder design pattern is for contructors.

Tony
  • 2,266
  • 4
  • 33
  • 54

6 Answers6

6

If I face a method that has too many parameters I do the following steps usually:

  1. I try to identify an entity these parameters are related to and check if Preserve Whole Object refactoring can be used.

    You are getting several values from an object and passing these values as parameters in a method call. Send the whole object instead.

  2. If all these parameters are independent and I want to increase number of parameters I use another one common solution - Introduce Parameter Object refactoring.

    You have a group of parameters that naturally go together. Replace them with an object.

    In order to build that object other techniques and patterns can be used (e.g. Builder, Method chaining, Fluent interfaces).

Ilya Palkin
  • 14,687
  • 2
  • 23
  • 36
3

If the parameters naturally go together they can be substituted with the Parameter Object. If you don't want a long list of parameters in the constructor of the Parameter Object you can use the Builder design pattern to construct it. Another somewhat relevant technique is Preserve Whole Object.

zafarkhaja
  • 2,562
  • 1
  • 20
  • 22
2

You are right with Builder, depends on whether those params are mandatory or not.

I would personally start with http://en.wikipedia.org/wiki/Single_responsibility_principle because method (and constructors or classes) with many parameters smells. I mean, are those parameters related, is the method logic related together? Does it make any sense?

If those params has some relations, they could fit into some kind of domain entity.

Martin Podval
  • 1,097
  • 1
  • 7
  • 16
1

If number of parameters is dynamic, you can use double brace initialization:

public static void main(final String[] args) {
    method(new HashMap<String, Object>(){{
        put("p1", new Object());
        put("p2", new Object());
    }});
}

private static void method(Map<String, Object> params){

}

It has some drawbacks, but still viable approach. Be careful every call site will have it's own anonymous class. There also might be some problems with type safety. Instead of String-based keys, you can use enums. Instead of Map any custom type could be used, Map just is the most common. DBI is more useful then varargs in case of dynamic parameters length.

Mikhail
  • 4,175
  • 15
  • 31
  • @atamanroman you should report your concerns to Groovy developers, for example. Or any other JVM based scripting language developers. They'd be cheered up. This approach is fully supported by JLS, so it's no a hack. – Mikhail Jan 27 '14 at 08:49
  • Thank you. An interesting suggestions. I did not have dynamic parameters, but any help is appreciated – Tony Jan 27 '14 at 08:57
  • 1
    @Mikhail This has nothing to do with any other jvm language but java. In java, double brace initialization is a not-that-well-known syntax trick with serious drawbacks, performance implications and zero advantages. – atamanroman Jan 27 '14 at 09:39
1

Builder pattern is used to construct a complex object step by step and the final step will return the object. The process of constructing an object should be generic so that it can be used to create different representations of the same object.

“Separate the construction of a complex object from its representation so that the same construction process can create different representations”

nikhilgupta86
  • 472
  • 3
  • 15
  • Yes you are right. But what is a solution ? – Tony Jan 27 '14 at 08:48
  • Based on the logic divide the method into more fine grained methods which also reduce the number of parameters in the method and finally using builder pattern get the result. This approach has two benefits 1) The number of parameters will be reduced 2) program become more modular. – nikhilgupta86 Jan 27 '14 at 08:52
  • Builder is great, but alot of code is required. In case of just one method this pattern is superfluous. There should be a a reason, like for Hibernate criteria. – Mikhail Jan 27 '14 at 09:00
0

If you need a lot of parameters - something wrong...

method not static -> You can define some parameters as fields.

If you realy need do it like this, maybe better create class A.AMParameter(int a, int b, boolean c, List<>...), and pass it in m (A.AMParameter), or use Map...