OOP Coding Style – Should Everything Be Initialized in the Constructor?

coding-styledesignobject-oriented

I still consider myself as an apprentice programmer, so I'm always looking to learn a "better" way for typical programming. Today, my coworker has argued that my coding style does some unnecessary work, and I want to hear opinions from others.
Typically, when I design a class in OOP language (Usually C++ or Python), I would separate the initialization into two different parts:

class MyClass1 {
public:
    Myclass1(type1 arg1, type2 arg2, type3 arg3);
    initMyClass1();
private:
    type1 param1;
    type2 param2;
    type3 param3;
    type4 anotherParam1;
};

// Only the direct assignments from the input arguments are done in the constructor
MyClass1::myClass1(type1 arg1, type2 arg2, type3 arg3)
    : param1(arg1)
    , param2(arg2)
    , param3(arg3)
    {}

// Any other procedure is done in a separate initialization function 
MyClass1::initMyClass1() {
    // Validate input arguments before calculations
    if (checkInputs()) {
    // Do some calculations here to figure out the value of anotherParam1
        anotherParam1 = someCalculation();
    } else {
        printf("Something went wrong!\n");
        ASSERT(FALSE)
    }
}

(or, python equivalent)

class MyClass1:

    def __init__(self, arg1, arg2, arg3):
        self.arg1 = arg1
        self.arg2 = arg2
        self.arg3 = arg3
        #optional
        self.anotherParam1 = None

    def initMyClass1():
        if checkInputs():
            anotherParam1 = someCalculation()
        else:
            raise "Something went wrong!"

What is your opinion about this approach? Should I refrain from splitting the initialization process? The question is not only limited to C++ and Python, and answers for other languages are also appreciated.

Best Answer

Though sometimes it is problematical, there are many advantages to initializing everything in the constructor:

  1. If there is going yo be an error, it happens as quickly as possible and is easiest to diagnose. For example, if null is an invalid argument value, test and fail in the constructor.
  2. The object is always in a valid state. A coworker can't make a mistake and forget to call initMyClass1() because it isn't there. "The cheapest, fastest, and most reliable components are those that aren't there."
  3. If it makes sense, the object can be made immutable which has lots of advantages.
Related Topic