Accumulative Construction

A while back someone asked for guidance on what order should polymorphic construction occur in C# classes.  I guess I had never really put much thought into it before and have never seen other guidance on the topic; but, I can see where this can become a valid design consideration.


 Polymorphic construction is when a class has more than one constructor.  If one constructor reuses the services of another constructor, I’ve coined the term Accumulative Construction, i.e. through successive calls to potentially many constructors.


Here’s some guidance that serves me well:



Polymorphic constructors should be called from most specific to least specific.


For example; you may want to write class with several parts to its invariant, where one or many of those parts may have defaults or are optional.  In this case you may provide several constructors allowing the user to construct your object in different combinations of required and optional information.  In cases like this, the most specific constructors should call least specific constructors.



    internal class Person


    {


        int age;


        String firstName;


        String middleName;


        String lastName;


 


        public Person ( String firstName, int age )


        {


            this.firstName = firstName;


            this.age = age;


        }


 


        public Person ( String firstName, String lastName, int age )


            :this(firstName, age)


        {


            this.lastName = lastName;


        }


 


        public Person ( String firstName, String middleName, String lastName, int age )


            :this(firstName, lastName, age)


        {


            this.middleName = middleName;


        }


 


        // properties and methods follow…


    }


This nicely matches generally accepted exception handling: order catch blocks from most to least derived class (which is detected automatically by the C# compiler).

7 thoughts on “Accumulative Construction”

  1. Hello,

    – Once a Person object is created, I feel there’s a need for a method like this:
    Initialize(firstName, middleName, lastName, aAge)

    Person p = new Person(“f”,”m”,”l”,4);

    p.Initialize(“f1″,”m1″,”n1”,11);
    p.Initialize(“f2″,”m2″,”n2”,22);
    p.Initialize(“f3″,”m3″,”n3”,33);
    //etc

    How would you write the Initialize method in order to avoid copy paste from the
    constructors ??

    public Initialize( String firstName, String middleName, String lastName, int age)
    {
    //assignments

    this.firstName = firstName;
    this.middleName = middleName;
    this.lastName = lastName;
    this.age = age;

    }

    If I do this, all the benefit of having the initialization code in one place, vanishes.

  2. @Charles. I disagree. “Construction” is tantamount to “initialization”. In your example, it doesn’t make sense to “initialize” several times.

    In object-oriented design we want to model the behaviour of real-world object through the design of our classes. With a person type I would have specific methods that model the behaviour of a person. A person never “Initializes” itself. It may:

    public ChangeName(IEnumerable givenNames, String surname)
    {
    /…/
    }
    public Age(int yearsToAddToAge)
    {
    //…
    }

    You wouldn’t arbitrarily re-initialize a person in response to some action. Given names and age properties of a person, you’re either going to change the name of a person or age them. Having ChangeName and Age behaviour makes it explicit how to use Person and as a result makes it explicit what you are doing to a Person object.

  3. With object initializers in C# 3.0 I think many of old constructors can/should be removed.
    Only constructors that demand essential information for object construction should exist.

  4. @Peter. It depends on the type. Domain Model types aren’t necessarily going to have a property setter for each and every attribute of the type. The recommended practice is to model behaviour with Domain Model types; they aren’t data containers. In cases like this, object initializers can’t be used.

    Also, types used in multithreaded environments will tend to be immutable; meaning their value can’t change after construction. In cases like this object initializers can’t be used either.

  5. Hello

    When I have asked about initialization,
    I was thinking to do something useful afterwards:

    Thus, it makes sense to “initialize” several times.

    Person p = new Person(“f”,”m”,”l”,4);
    p.Initialize(“f1″,”m1″,”n1”,11);
    p.DoSomething();

    p.Initialize(“f2″,”m2″,”n2”,22);
    p.DoSomething();

    p.Initialize(“f3″,”m3″,”n3”,33);
    p.DoSomething();

    etc

    Many thanks.

  6. @Charles. It looks like you’re trying to reuse object instances. I don’t recommend that because now the type must support reuse in that way. Unless Initialize can guarantee that the state is complete reset upon every call (and it can’t) your implementation of Person is dependent on it’s usage. This limits reuse and makes for a tightly coupled design.

    Instance re-use like this is a premature optimization. The GC will do much of that for you, making any perceived savings negligible at the expense of readability and maintainability.

  7. @Charles. Also, multiple initialization is an oxymoron; it makes the interface and the resulting code confusing.

Leave a Reply

Your email address will not be published. Required fields are marked *


*