views:

100

answers:

7

I have a strong feeling that I do not know what pattern or particular language technique use in this situation.
So, the question itself is how to manage the growing parameter list in class hierarchy in language that has OOP support? I mean if for root class in the hierarchy you have, let's say 3 or 4 parameters, then in it's derived class you need to call base constructor and pass additional parameters for derived part of the object, and so forth... Parameter lists become enormous even if you have depth of inheritance more than two.
I`m pretty sure that many of SOwers faced this problem. And I am interested in ways how to solve it. Many thanks in advance.

+2  A: 

Alternatives:

  • Use setter injection instead of constructor injection
  • Encapsulate the parameters in a separate container class, and pass that between constructors instead.
skaffman
I agree with your first point but isn't the second point re. encapsulating the parameters simply shifting the problem elsewhere? What value does it add in doing this?
Adamski
Because you wouldn't have to update the constructor signature on every class in your hierarchy.
skaffman
And also when creating a parameter class you can see, do you really initialize your obkect with something that parameter object hides behind it (I mean it`s abstraction). If you initializeftp class with login, password, port and some more things that you decided to wrap with Credentials class it`s ok and it will let your reader to see that азе need credentials that are login, password, port, ...
Yaroslav Yakovlev
+4  A: 

Constructors with long parameter lists is an indication that your class is trying to do too much. One approach to resolving that problem is to break it apart, and use a "coordinator" class to manage the pieces. Subclasses that have constructor parameter lists that differ significantly from their superclass is another example of a class doing too much. If a subclass truly is-a superclass, then it shouldn't require significantly more data to do its job.

That said, there are occasional cases where a class needs to work on a large number of related objects. In this situation, I would create a new object to hold the related parameters.

kdgregory
+1  A: 

Possibilities:

  • Perhaps your class(es) are doing too much if they require so much state to be provided up-front? Aim to adhere to the Single Responsibility Principle.
  • Perhaps some of these parameters should logically exist in a value object of their own that is itself passed in as a parameter?
  • For classes whose construction really is complex, consider using the builder or factory pattern to instantiate these objects in a readable way - unlike method names, constructor parameters lack the ability to self document.
teabot
+1  A: 

Don't use constructors to initialize the whole object at once. Only have it initialize those things which (1) are absolutely required for the existence of the object and (2) which must be done immediately at its creation. This will dramatically reduce the number of parameters you have to pass (likely to zero).

For a typical hierarchy like SalariedEmployee >> Employee >> Person you will have getters and setters to retrieve and change the various properties of the object.

John Feminella
+1  A: 

Seeing the code would help me suggest a solution..

However long parameter lists are a code-smell, so I'd take a careful look at the design which requires this. The suggested refactorings to counter this are

However if you find that you absolutely need this and a long inheritance chain, consider using a hash / property bag like object as the sole parameter

public MyClass(PropertyBag configSettings) 
{
  // each class extracts properties it needs and applies them
  m_Setting1 = configSettings["Setting1"]; 
}
Gishu
A: 

You could create a new class that contains all the parameters for the contructors. Much like the EventArgs class in the .NET Framework. This class can then be inherited to add more properties for inherited class constructors.

C# quick example:

public class ConstructorInfo
{
  string param1;
  long param2;
  //...
}

public class MyClass
{
  public MyClass(ConstructorInfo info)
  {
    //obtain parameters from info
  }
}

// Add parameters to inherited classes
public class InheritedConstructorInfo : ConstructorInfo
{
  DateTime param3;
  //...
}

public class MyInheritedClass : MyClass
{
  public MyInheritedClass(InheritedConstructorInfo info)
    : base(info)
  {
    //obtain parameters from info.
    //note that base constructor can be called with same info-object.
  }
}

Of course, there's no need to create the InheritedConstructorInfo class, if you are able to place all the needed properties directly in ConstructorInfo.

Bernhof
A: 

Another tip: Keep your class hierarchy shallow and prefer composition to inheritence. That way your constructor parameter list will remain short.

Adamski