Why use __construct?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
aditya2071990
Forum Contributor
Posts: 106
Joined: Thu May 22, 2008 11:30 am
Location: Hyderabad, India
Contact:

Why use __construct?

Post by aditya2071990 »

If I can instantiate an object and set a property's value using $this, then why use constructors?

Look at this:

Code: Select all

 
class employee
{
    public $salary;
    
    function __construct($salary)
    {
        $this->salary = $salary;
    }
}
 
In another file,

Code: Select all

 
$employee=new employee('10,000');
 
Why go through all of that, when even without the constructor method, we could have simply done this:

Code: Select all

 
$employee=new employee();
$employee->salary='10,000';
 
That way, at least we'll know for sure which property exactly got a value upon instantiation... what if we forget which property the constructor was used?

I just want to know for sure the advantage of using a constructor, and nobody seems to have written anything about it before...
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Why use __construct?

Post by Christopher »

I think the theory is that the constructor args allow you to create a fully useful object, even it if requires some values to be given to the object to become fully useful.

If an employee must have a salary defined, then this is a fully usable object:

Code: Select all

$employee=new employee(10,000);
And you will get an error if you don't provide all the required information.

Otherwise you will often have this problem:

Code: Select all

$employee=new employee();
// this method can be called but is not valid yet because salary not set
$employee->getMonthlyPay();
You don't want the method calls be order dependent like can happen in procedural programming.
(#10850)
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Why use __construct?

Post by Eran »

The thing is you can have logic inside the constructor which should be run on each new object instance. If it's just value assignment without additional logic, then there isn't much difference between the approaches.
User avatar
aditya2071990
Forum Contributor
Posts: 106
Joined: Thu May 22, 2008 11:30 am
Location: Hyderabad, India
Contact:

Re: Why use __construct?

Post by aditya2071990 »

Thanks! I overlooked the fact that constructors aren't for simple value assignment, and that you can make stuff happen without actually having to call a method... :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Why use __construct?

Post by alex.barylski »

Constructor arguments must be provided which *guarantees* a properly initialized object...
User avatar
aditya2071990
Forum Contributor
Posts: 106
Joined: Thu May 22, 2008 11:30 am
Location: Hyderabad, India
Contact:

Re: Why use __construct?

Post by aditya2071990 »

How could the employee class have been improperly initialized?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Why use __construct?

Post by alex.barylski »

Exactly how arborint stated above.

Murphys law...if something can wrong it will. That being said, using ctor() arguments guarantees proper initialization, whereas allowing a user to set the properties after construct() is asking for additional tech support. Sooner or later, you or someone else will call a method like getTotalValue() or whatever and the variable/member data it calls on will not have been properly initialized and the results will not be what you expected.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Why use __construct?

Post by Ollie Saunders »

Murphys law...if something can wrong it will.
In real life there's an element of chance, the possibility for serendipity, and for seemingly random failure. For instance, you can be watching TV and have it suddenly burst into flames. That can happen and has happened substantiating Murphy's law.

But why is Murphy's law useful? On the face of it Murphy's law seem to strike fear and doubt into everything, which wouldn't be a particularly nice thing to quote anytime; "Oh, guess what? Everything sucks! So you might as well give up and die, painfully and horribly, of course, nothing but the worst for you!". But actually, Murphy's law is relieving because when something goes wrong (and stuff does) Murphy's law reminds us of the possibility for things to fail randomly and, more importantly, for failure to be outside of our control. Murphy's law says, "It's OK, you couldn't help it. Sometimes bad stuff just happens." Thanks Murphy, you're swell!

The reason I mention all this is because I actually don't agree that Murphy's law is being used correctly here. Failures in software are almost never random. If you bugger up your object state it's not because of an electrical short you couldn't have helped it's because of you, the programmer. As programmers we have an enormous amount of power and control over our machines. We feel the benefit of this when we achieve -- the credit belongs entirely to us and we feel great. But that means the blame is entirely ours when something goes wrong.

If you approach code superstitiously believing that the way it works is in some way unpredictable and magical, I'm afraid, you're operating under a false concept. You might be trying to make yourself feel better about why it failed but, sorry, "that was your fault and you should probably fix it now". The only way that opinion is reasonable is when you're dealing with somebody else's code that you can't see but even then that is better conceptualised a preordained system, however complex, than it is anything random.

I've noticed a correlation where reduced understanding leads increasingly to explanations of randomness. Even a call to mt_rand() is predictable, it's just deliberately so complex that we can't possibly explain it from outside observation. So, I assure you all, everything about what will and won't work, will and won't be reliable, will and won't break unexpectedly, can be explained. And by declaring some behaviour random one is, in effect, declaring their own bewilderment.

N.B. This isn't aimed personally at PCSpectra. A lot of people think this, he just reminded me of this problem and do I took this opportunity to address it for the benefit of those in this thread.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Why use __construct?

Post by Christopher »

Ollie Saunders wrote:
PCSpectra wrote:Murphys law...if something can wrong it will.
The reason I mention all this is because I actually don't agree that Murphy's law is being used correctly here.
Actually, I think PCSpectra has it right about constructors -- even if he makes Murphy's law too general. The thing about Murphy's Law is that it is not "if something can wrong it will", it is "if you design a way that something can go wrong, someone will do it that way." It is a subtle but important difference. It is the reason that all of our plugs can only be plugged into the proper plug and in the proper orientation. That was specifically the kind of thing that Murphy was interested in. The saying has taking a broader, more fatalistic meaning over time.

In relation to constructors I think Murphy's Law does apply. If you allow programmers to create an object that will do something wrong, then programmers will use the object in a way that will make that wrong thing happen. That is why it is important to have the ability to initialize objects by having required parameters and code in the constructor.
(#10850)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Why use __construct?

Post by Ollie Saunders »

Putting the original meaning of Murphy's law aside, I agree that the purpose of constructors is to protect the programmer. It is a poka-yoke device or safety feature much like the design of the plug that arborint mentions.

It might seem unlikely (safety is always good, right?) but there is actually both critical as well as advocating schools of thought on safety in code.

The safety advocates see software development as an engineering discipline where writing code should be made trivial with the real work being done by experienced designers before programming begins. Safety mechanisms such as type checks and constructors protect the code monkeys from mucking up the experienced designers' designs; the assumption being that without those mechanisms they would muck it up and that checks for things help eliminate faults.

So you see, safety advocation is something that evolved from an engineering approach to software development based on the assumption that software development is a form of engineering. If you're a safety advocate and you don't believe that software development is a form of engineering then why are you advocating safety?

The safety critics take a different approach. They believe that programming is less like engineering and a little more like writing or perhaps art (art is a step too far in my opinion). Safety critics believe the process of writing code is a clarifying one where the understanding of what is being written emerges as a result of writing it. I've heard this described as "the code speaks to you". This might sound a little fantastical and airy-fairy to some but, believe me, it's preferable to BDUF, and incidentally, a lot more enjoyable.

Because the safety critic doesn't have a design team above him (he is the designer) he doesn't need to protect himself from himself. Nor does he need to protect his work colleagues from himself because they are all designers (it is assumed they know what they're doing) and they appreciate the need to change the design from time to time. Instead the focus moves from protection to liberation in order to express whatever it is you're trying to implement in a way most amenable to comprehension and future modification. For those goals safety features get in the way.

Back to constructors. I don't like 'em. The work I'm doing in Fluidics attempts to codify an alternative to constructors: chainable setters and getters and a convention for construction methods -- an idea as old as SmallTalk, which seemed to work just fine for those guys.

I hope all this helps someone.
User avatar
aditya2071990
Forum Contributor
Posts: 106
Joined: Thu May 22, 2008 11:30 am
Location: Hyderabad, India
Contact:

Re: Why use __construct?

Post by aditya2071990 »

OMG, that was sooo gigantic!!!

I'm sorry I'm laughing at such a serious matter, but a very small question from me led to such a great scholarly debate and discussion! I love this board :D
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Why use __construct?

Post by Ollie Saunders »

This doesn't happen routinely. You asked why (well done) which, to answer, requires examination of motivations and origins amongst others things.

Also I'm saving what I say on this topic and related ones to add to the documentation of my library so I have another motivation.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Why use __construct?

Post by alex.barylski »

Back to constructors. I don't like 'em. The work I'm doing in Fluidics attempts to codify an alternative to constructors: chainable setters and getters and a convention for construction methods -- an idea as old as SmallTalk, which seemed to work just fine for those guys.
To what benefit?

What I see, is possibly a clearer interface or more explicit, but at what cost?

Unless your setters validate the state of the object (to ensure proper initialization sequence -- if needed) someone could just as easily forget to add the required setter at initialization. Relying on setters (whether chained or not) ultimately suffer from the same flaw as directly setting the property values, unless you perform the validation checks in each setter, which would be over-engineering IMHO.

It's rare in PHP (if ever) you need to ensure proper initialization of an object, you can usually initialize one property before or after another without much consequence, but ctors() in technologies like Windows development and MFC, proper sequence can be important and construction initilazation becomes far more important.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Why use __construct?

Post by Ollie Saunders »

Unfortunately, in order to fulfil the safety critic's ideology you have to diverge from conventional PHP quite a lot and in a way that requires some library support. I'm writing that library. The process is not too dissimilar from language design, which I've also done a little bit of. I can answer your points but I'll start to be just showcasing how I am or will be doing things in Fluidics and how those things fit together. I feel a little uncomfortable about doing that because it's not in a fit state for use yet (and something has just come up so I might not finish it after all :oops:).

What I'm saying here is that PHP, unaltered, isn't acceptable to the safety critic's style of programming. If you're one of those people who never really understood OO this is partly why. The benefits of OO are encumbered by safety mechanisms that are ingrained PHP and PHP culture. (Not just PHP though, not by any means).
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Why use __construct?

Post by alex.barylski »

Unfortunately, in order to fulfil the safety critic's ideology you have to diverge from conventional PHP quite a lot
I'm lost, who are these safety critics? Conventional PHP? Not using ctors() in favour of chained getters would be more like going against accepted OOP best practices, much like how functional programming advocates stateless programming. It sounds as though you are challenging the paradigm, not just something as trivial as PHP itself.

This OK, I mean functional programming does have it's advantages, but OOP has become the defacto standard for a reason.
What I'm saying here is that PHP, unaltered, isn't acceptable to the safety critic's style of programming. If you're one of those people who never really understood OO this is partly why. The benefits of OO are encumbered by safety mechanisms that are ingrained PHP and PHP culture. (Not just PHP though, not by any means).
Defensive programming is a technique or methodology, not a programming language. You can build librarieséframeworks to assist and sometimes prevent some errors from happening but until software is writing itself, I think we will always need manual intervention in this regard.

I think it would help me if you could demonstrate what your talking about with some code examples.
Post Reply