Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logic inside constructor

Is it a good idea to have logic inside __constructor?

public class someClass
{
    public function __construct()
    {
        //some logic here
    }

So far I thought that it is fine; however, this reddit comment suggests the opposite.

like image 643
sitilge Avatar asked May 10 '16 17:05

sitilge


2 Answers

As @Barry wrote, one of the reasons is related to unit-testing, but it's just a side-effect.

Let's take the worst case scenario: you have a "class", which only has a constructor (you probably have seen such examples). So ... why was it even written as a class? You cannot alter it's state, you cannot request it to perform any task and you have no way to check, that it did what you wanted. You could as well used a linear file and just included it. This is just bad.

Now for a more reasonable example: let's assume you have a class, which has some validation checks in the constructor and makes a new DB connection in it. And and then it also has some public methods for performing various tasks

The most obvious problem is the "makes a new DB connection" - there is no way to affect or prevent this operation from outside the class. And that new connection is going off to do who-knows-what (probably loading some configuration and trying to throw exceptions). It also constitutes a hidden dependency, for which you have no indication, without inspecting the class's code.

And there is a similar problem with code, that does validations and/or transformations of passed parameters. It constitutes hidden logic (and thus violating PoLA. It also makes your class harder to extend, because you probably will want to retain some of that validation functionality, while replacing other part. And you don't have that option. Because all of that code gets run whenever you crate a new instance.

Bottom line is this - logic in constructor is considered to be a "code smell". It's not a mortal sin (like using eval() on a global variable), but it's a sign of bad design.

like image 124
tereško Avatar answered Sep 22 '22 12:09

tereško


No it isn't a good idea for automated testing. When testing you want to be able to "mock" objects that allow you to control the logic especially in terms of interfaces. So if you place logic in the constructor then it is very hard to test as you must use the real object.

here is a fantastic talk with much more detail on why not to put logic in constructor (google tech talk by Misko Hevery) https://www.youtube.com/watch?v=RlfLCWKxHJ0

like image 40
Barry Avatar answered Sep 20 '22 12:09

Barry