Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is doing a lot in constructors bad? [closed]

Making all fields final is in general a good idea, but sometimes I find myself doing everything in the constructor. Recently I ended up with a class doing actually everything in the constructor, including reading a property file and accessing a database.

On one hand, this is what the class is for, it encapsulates the data read and I like creating objects completely initialized. The constructor is not complicated at all as it delegates most of the work, so it looks fine.

On the other hand, it feels a bit strange. Moreover, in this talk at about 17:58 there are good reasons for not doing much work in constructor. I think I can eliminate the problem by passing appropriate dummies as constructor arguments.

The question remains: Is doing a lot of work (or even all the work) in constructors bad?

like image 289
maaartinus Avatar asked Aug 13 '11 04:08

maaartinus


People also ask

Is doing a lot in constructors bad?

So yes, doing a lot in constructor is a bad idea in my opinion. Generally I just put some field initializations into the constructor and make an init method to invoke when everybody is on board. I think that your problems may have been caused by violation of SRP and not the constructor doing actual work. – Emily L.

What should not be done in constructor?

Don't use init()/cleanup() members. If you have to call init() every time you create an instance, everything in init() should be in the constructor. The constructor is meant to put the instance into a consistent state which allows any public member to be called with a well-defined behavior.

Is it good practice to throw exception in constructor?

The short answer to the question “can a constructor throw an exception in Java” is yes! Of course, properly implementing exceptions in your constructors is essential to getting the best results and optimizing your code.

Are constructors supposed to be void?

Constructor is not like any ordinary method or function, it has no return type, thus it does not return void. Constructors don't create objects.


2 Answers

I think that "Doing work in the constructor" is okay...

... as long as you don't violate Single Responsibility Principle (SRP) and stick to using Dependency Injection (DI).

I have been asking myself this question too lately. And the motivation against doing work in the constructor that I have found are either:

  • It makes it hard to test
    • All examples I have seen have been where DI wasn't used. It wasn't actually the fault of the constructor doing actual work.
  • You might not need all the results that your constructor calculates, wasting processing time and it's hard to test in isolation.
    • This is basically a violation of SRP, not a fault of the constructor doing work per say.
  • Old compilers have/had trouble with exceptions thrown in constructors, hence you shouldn't do anything other than assign fields in constructors.
    • I don't think it's a good idea to write new code taking historical compiler deficiencies into account. We might as well do away with C++11 and all that is good all together if we do.

My opinion is that...

... if your constructor needs to do work for it to adhere to Resource Acquisition Is Initialization (RAII) and the class does not violate SRP and DI is properly used; Then doing work in the constructor is A-Okay! You can even throw an exception if you'd like to prevent usage of a class object whose initialization failed completely instead of relying on the user to check some return value.

like image 133
Emily L. Avatar answered Oct 20 '22 01:10

Emily L.


This is a very open-ended question, so my answer will try to be as general as possible...

Doing work in constructors isn't as "bad" as it used to be years ago when exception handling wasn't as prevalent and evolved as it is today. You'll notice that the Google Tech talk primarily looks at constructors from a Testing perspective. Constructors have been historically very very difficult to debug so the speaker is correct that doing as little as possible in a constructor is better.

With that said, you'll notice that he's also touching on dependency injection/the provider pattern which is notorious for complicating constructors. In such a case, leaving ONLY provider/DI code in the constructor is preferred. Again, the answer depends on what patterns you're using and how your code "fits" together.

The entire point of using a constructor is to create a neat object that can be used immediately; i.e. new Student("David Titarenco", "Senior", 3.5). There's no need to do david.initialize() as it would be entirely silly.

Here's some of my production code, for example:

    Config Conf = new Config();     Log.info("Loading server.conf");     Conf.doConfig(); 

In the above case, I decided not to do anything with the constructor (it's empty) but have a doConfig() method that does all the disk i/o; I've often thought that the doConfig() method is just pointless and I should do everything in the constructor. (I only check out the config file once, after all.)

I think that it's entirely dependent on your code and you shouldn't think that putting "stuff" in your constructor is a bad thing. That's what constructors are for! Sometimes we get carried away with OOP (getThis, setThat, doBark) when really all a class needs to do is a load a config file. In such cases, just put everything in the constructor and call it a day!

like image 35
David Titarenco Avatar answered Oct 19 '22 23:10

David Titarenco