tags:

views:

134

answers:

3

I have designed a hierarchy, every class has 2 readonly properties mapped to 2 private fields.

Every class has a cosntructor that inherits the parent class one.

The problem is that at every level of hierarchy the number of parameters increase of 2:

TBaseClass.Create (par1, par2);
TSubClass.Create(par1, par2, par3, par4);
TSubSubClass.Create(par1, par2, par3, par4, par5, par6);
[...]

Is it ok to have constructors with 6-8 parameteres? After creation my objects should be immutable, so this is why I try to initialize all fileds in the constructors.

Is there another technique you can suggest or should I go with the above mentioned approach? Thanks.

+3  A: 

As long as they're well-documented, I've never had any stigma against functions with large numbers of parameters. So an 8-param constructor wouldn't scare me.

However, I can see where the explosion-of-params could occur here, especially if you start adding more than 2 properties per object. I could also see an uncomfortable proliferation of constructor overloads, if some of those params can be defaulted/optional.

With that in mind, you might want to encapsulate the complexities of setting all those params, by using a construction pattern. Builder comes to mind, though Factory or Prototype might also be useful.

mikemanne
I see. Builder is exactly what I need. Could you suggest a good resource for design patterns? I read introductory books as Larman's, but they focus on the OOAD in broad terms.
You can't use "Builder" to get away from your 6,8,10 constructor parameters: Assuming parameters (1,2) can't be deduced from (3,4), you still need to specify all of (1,2,3,4) no matter how you create your object.
Cosmin Prund
Perhaps, but constructing objects through several well-named and calls and/or properties is usually a lot easier to read and maintain than changing the 6th boolean in a row to TRUE in a 15-argument constructor.
Paul-Jan
Cosmin: since the properties are read-only, you make a good point: the object would still have c'tors with a large number of arguments. However, I think there's still value in encapsulating that creation/configuration logic in 1 builder, rather than spread out among any objects which might instantiate it.
mikemanne
user193665: wikipedia has concise descriptions of many of the most common/popular patterns. The orginal "gang-of-four" book (http://en.wikipedia.org/wiki/Design_Patterns_%28book%29) is the canonical reference, though there have been several more patterns (and even families of patterns) documented since then.
mikemanne
Thanks to all for the valuable feebdack.
+1  A: 

Best to stick with conventions when you can. A Builder implies a sequential or multiple object creation process. Abstract Factory is more appropriate for creating a single object from a hierarchy.

Having said that, the regularity does seem a little odd. Does SubClass3 in fact need all 6 properties or only it's two? Remember LSP - SubClass3 is supposed to be completely substitutible for BaseClass so at each level the new ancestor assumes responsibility for the entire set, which is usually more than just passing them back through constructors.

Sisyphus
It is an example, what I am doing is a set of classes to build the main menu of an application. As far as the hierarchy is made every parameter is mandatory.
A: 

Why don't you let those properties be writable and protect the object by casting it to an interface? Like this:

type
  IMyObject = interface
    function GetProperty1(): integer;
    function GetProperty2(): boolean;
  end;

  TMyObject = class(TInterfacedObject, IMyObject)
  public
    constructor Create();
    function GetProperty1(): integer;
    function GetProperty2(): boolean;
    procedure SetProperty1(Value: integer);
    procedure SetProperty2(Value: boolean);
  end;

function CreateMyObject: IMyObject;
var obj: TMyObject
begin 
  obj := TMyObject.Create;
  obj.SetProperty1(45);
  obj.SetProperty2(false);
  Result := obj;
end;
himself