Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Possible Duplicate:
Are there guidelines on how many parameters a function should accept?

I have got class with 30 variables (it is application form), so I wonder what is the best practice to organize class creation.

Should I use huge constructor:

MyClass mc = new MyClass(a, b, c, d)

Or setters:

MyClass mc = new MyClass();
mc.setA(a);
mc.setB(b);
mc.setC(c);
mc.setD(d);

What is the best practice in OOP for such situation? I saw similar question, but now I don't need immutability.

share|improve this question
4  
7  
C# gives you the best of both via its initializer syntax: MyClass mc = new MyClass { A = a, B = b, C = c, D = d }; –  Ant Jun 14 '12 at 21:42
7  
The answer is highly dependent on the programming language. –  kevin cline Jun 14 '12 at 22:08
    
Not enough information. We need to know the usage semantics. Is this really a class that encapsulates its properties or a simple property bag. –  Loki Astari Jun 14 '12 at 23:26
    
Huh? I have built many GUI forms and I never had to supply more than 5 arguments. Can you give an example of what you are trying to do with names other than a, b, c, and d? –  Job Jun 15 '12 at 0:31
add comment

marked as duplicate by Jarrod Roberson, Loki Astari, gnat, Walter, ChrisF Jun 16 '12 at 22:25

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

6 Answers

The main difference between your 2 examples is that the user of the class is forced to use the constructor but not forced to set its state via set methods.

You should place all arguments in the constructor that will setup your instance in the correct state. Other 'setting' methods should be optional.

What I would do in your case is identify within your 30 variables comman themes that in themselves can be broken down into DTO's. So you might have instead (for example):

MyClass mc = new MyClass(personInfo, companyInfo, salaryInfo);

Addtionally you might want to look at whether your class is doing too much and whether you can limit the use of internal state by creating smaller component classes rather than having one large class.

share|improve this answer
add comment

There is a Third Option that is the most Object Oriented Idiom

The best thing to do is to use the Builder pattern.

The class has an default constructor, and you set all the required parameters and then call .build() or .materialize() or some appropriately named method validate and finalize the construction of the object and get return a reference to the completed object.

This can be used very successfully with the Fluent API design pattern as well.

Here is an example on how to enforce a Builder pattern API adherence to construct only valid objects. The blog post is about Java, but it applies to any statically type Object Oriented language that supports interfaces. It makes it very easy to know what you must do next with auto completion in an IDE as well.

I am not a big fan of the Fluent API pattern because it can be abused very easily and when it is the method chaining is very hard to diagnose exceptions, but in this particular case it is very appropriate.

share|improve this answer
add comment

The answer depends on how you use the class...

  • If you want your class to be immutable, you'll have to use constructor parameters.

  • If you want your class to be deserializable by relection based (de)serializers, you will need a default constructor and setters.

  • If your class isn't supposed to be immutable and you want consumers to be able to change all the properties during the objects' lifetime, then you will need to add setters anyway (or add modification methods, which may seem less straightforward to consumers).

  • If you do use the default constructor and properties approach, then you must make sure that the consumers can not invalidate the object's state by setting in an unexpected order, that default values are valid and that all the setters check things like ranges before applying the changes.
    If you have two (or more) dependant properties, either encapsulate them in a class, or make sure that if either of them is set (e.g. X is set), it changes the other's value (e.g. Y's value) if (Y's) current value doesn't not go together with the new value (of X).


Also, consider if your class really should be one class:

If it has 30 parameters, you may be breaking the OO principle of encapsulation - where each class does one thing and does everything for that one thing.

Perhaps you should be using composition of a few classes or, if you have a lot of common parameters between classes, perhaps you need one or more vertical classes that handles a specific aspect and can act on multiple classes (either using reflection or using additional classes in a visitor pattern).

share|improve this answer
add comment

I'd go with the huge constructor. It's simplest. If each call to the constructor uses different parameters (that is, you'd end up passing a lot of nulls), either make more constructors. The basic idea is keep the code to a minimum; make it as simple as possible. If you need to get real fancy setting values and the setters would be simpler, use them.

There's something sloppy about too many parameters, so you might want to see if you should be passing objects that each contain several parameter values. Don't strain yourself on this one, but if you've got 15 parameters, I betting you'll find a simpler way to do it.

Too many parameters are bad, but too many mindless setters aren't good either; there's no right answer. You have to choose the lesser of two weevils. This discusses setters better than I can.

share|improve this answer
add comment

Assuming you're not in a language that makes it convenient to write named parameters (e.g., Python or Common Lisp), you should consider whether your objects are considered to be read-only or read-write. If the former, you must set values from the constructor, but otherwise it's really up to you as long as you have setters (or your language's equivalent). Given that you're dealing with 30 variables though, I'd really consider using something which would let you avoid having to write out constructors with that many arguments. Even 10 would be rather too many for sanity…

share|improve this answer
    
C# 4 also introduced named parameters. –  R0MANARMY Jun 14 '12 at 23:27
add comment

I would ask yourself if you will ever really be constructing this giant object, or will it always be loaded from a database?

I cannot see any reasons to have an object this large constructed with values coming from code.

If this thing is always saved and loaded from a database or a file, give it a simple default constructor and focus on getting the object-database mapping or serialization correct.

share|improve this answer
    
it says right in the first sentence (it is application form) which implies it is coming dynamically from the end user, not some database input. –  Jarrod Roberson Jun 15 '12 at 0:47
    
@JarrodRoberson: Then it needs a GUI binding. Or it needs a HTML POST binding. Seriously, what would it use a constructor for? –  Zan Lynx Jun 15 '12 at 3:05
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.