1

I have a class with many members (~20). I would like to initialize it nicely so a constructor is not an option (due to the many parameters) because of the bad code readability.

So I tried to use a Builder DP. The only problem with it is that it's very nasty when it comes to extending such a class.

Any suggestion on what Design patter should I use to deal nicely with this situation (class with many members)?

Thanks a lot!

Vitali Melamud
  • 1,267
  • 17
  • 40

3 Answers3

1

20 fields with no defaults is an awful lot. There must be some way to either split the class into multiple classes or group some of the fields into Compound objects.

For example if you have fields for street, country, district etc you could group those all into a single Address object.

If you can do that a couple of times then your constructor should become manageable.

Also if you have 20 fields without any defaults, then you have to specify all the fields anyway so the Builder pattern loses its value. You might as well use a constructor.

dkatzel
  • 31,188
  • 3
  • 63
  • 67
1

As you say, 20 fields is a lot for a constructor. Regarding readability, the pattern that comes to my mind is static factory methods (but in the sense of Joshua Bloch's Effective Java, not the Factory Method of GoF book).

As he says in the book (in its Item 1), static factory methods have names (unlike constructors) so that a static method with a well-chosen name is easier to use and the resulting client code easier to read.

class ManyFields {
    T a;
    U b;
    (...)
    V t;
}

That way, you could do things like

ManyFields.withAtoFzeroed(g, h, i, ..., t)
ManyFields.onlyGandJ(g, j)
ManyFields.consonantsZeroed(a, e, i, o, u)
(...)

That is, adapt/coin new static factory methods addressing different usage patterns in your code is easier to do and more readable.

Of course, having a set of default values would help on that, since the number of parameters needed in those methods would be reduced.

Besides, static factory methods do not have to create a new object each time they’re invoked, allowint predefined instances, caching, etc. As a result, if equivalent objects are requested often, you can improve performance with this technique, apart from highlighting the most typical objects used for your class.

Nevertheless, the efectiveness (in terms of readability) of a bunch of static factory methods usually depends on how well you can group those parameters in terms of common values, default values, etc. which usually arises the need of splitting such a big class into smaller classes and using composition (as @dkaztel suggests).

Anyway, when dealing with many constructor parameters, the best approach is usually a Builder.

Given you want to avoid it, you can improve also the readability using method chaining for your setters.

ManyFields obj = new ManyFields();
obj.a(A).b(B).d(D).t(T).v(V).f(F);

This answer about builders and fluent interfaces can also be useful.

Community
  • 1
  • 1
jalopaba
  • 8,039
  • 2
  • 44
  • 57
0

Maybe this is really silly, but you could make a new Entity class with a whole bunch of Setters. That'll let you build the object any way you like, either with a builder, loader, or whatever.

Then, make your current class accept a single parameter of that Entity type and in the constructor call some sort of Validate method on it to make sure it's complete, and then use the data stored in the Entity to power the class.

It might be a lot of boilerplate code to create the entity and its validation rules, but actual usage of the class will become very straight forward.

Erik
  • 3,598
  • 14
  • 29