init() or __contruct() Which would you say?
#1
Posted 19 August 2009 - 05:48 PM
The only reference I had where it said to use one over the other was with the Flex development where it said use init so you don't recall the construct more than once. (since flex you'll constantly initiate a class over and over - even the same class - same object).
The purpose of my use is just to set a page heading automatically (built for a calendar system, pulls the month and sets it to the title) so that you just put echo $this->title and regardless what month / year you have the proper heading for your calendar.
So should I call it in an init or a __construct?
Thanks for any feedback.
#2
Posted 19 August 2009 - 06:21 PM
So since I'm not using any of the Yii framework classes to inherit, I'll go about that method to allow overriding of the init function to any potential members who use my class later for an application.
I'm going to do
function __construct() { init(); } public function init() { // code in here }
I'm still open to anyones opinions

#3
Posted 24 August 2009 - 01:36 PM
public function init() { ... $this->_initialized=true; } public function getIsInitialized() { return $this->_initialized; }
This kind of thing is an indication that things have gone wrong.
Anyway, the suggestion to call initialisation methods from a constructor is absolutely normal. But please call it/them something meaningful; init() tells me absolutely nothing about what the method does.
#4
Posted 24 August 2009 - 02:13 PM

#5
Posted 24 August 2009 - 02:13 PM
auxbuss, on 24 August 2009 - 01:36 PM, said:
public function init() { ... $this->_initialized=true; } public function getIsInitialized() { return $this->_initialized; }
This kind of thing is an indication that things have gone wrong.
Anyway, the suggestion to call initialisation methods from a constructor is absolutely normal. But please call it/them something meaningful; init() tells me absolutely nothing about what the method does.
If you document what init is for would it really matter then? Like you document that the construct runs on a new instance, and then it calls the initiliazing function which calls all the default values and functions in the class to set.
Because in all theory, the only purpose I'm using the init is to make it public / private / protected sort of gig. The construct actually assigns variables and my init is now calling functions.
So is it a big deal to have it named init? I completely agree with having your functions and variables mean something to what you're using them for.
Anyway thanks for the input

#6
Posted 24 August 2009 - 02:45 PM
With an init() method, it is possible to configure an object after it is instantiated while before fully initialized. For example, an application component could be configured using app config. If you override its init() method, you will be sure that the configuration is applied and you can safely to check if everything is ready. Similar thing happens to a widget and other configurable components.
Even if init() is called within constructor rather than by another object, it has meaning. For example, in CApplication, there are preInit() and init(). They set up the life cycles of an application and may be overridden so that the customization only occurs at expected life cycles.
I agree with you that the method naming is very important. Here in Yii, init() method means that an object is already fully configured and some additional initialization work should be done in this method.
#7
Posted 24 August 2009 - 06:15 PM
qiang, on 24 August 2009 - 02:45 PM, said:
With an init() method, it is possible to configure an object after it is instantiated while before fully initialized. For example, an application component could be configured using app config. If you override its init() method, you will be sure that the configuration is applied and you can safely to check if everything is ready. Similar thing happens to a widget and other configurable components.
Even if init() is called within constructor rather than by another object, it has meaning. For example, in CApplication, there are preInit() and init(). They set up the life cycles of an application and may be overridden so that the customization only occurs at expected life cycles.
I agree with you that the method naming is very important. Here in Yii, init() method means that an object is already fully configured and some additional initialization work should be done in this method.
So I guess it's a bad idea to have functions that you would normally call to run an application called within the init in the event someone extends your class?
For example what I made this topic about was my calendar class application. I ended up passing 3 values through the constructor to assign (or assign default values) and then I call the init function which calls 2 or 3 functions to setup the application to be displayed (it builds the calendar, gets the month / year for the title bla bla).
But if someone extends the init function, they essentially overwrite the calls to make the calendar and all that. So should I just be ignoring using the init function and instead put those calls in the constructor - then make an empty init function in order for extensibility?
#8
Posted 24 August 2009 - 07:03 PM
#10
Posted 25 August 2009 - 06:21 AM
whoopass, on 24 August 2009 - 02:13 PM, said:
What concerns me is that it becomes the norm. I've seen the problems this "approach" can cause. Oddly, I'm about to start a job tidying up a system that is in trouble largely due to init() being used, obviously completely inappropriately. It's interesting to see that this seems to have come from Zend, because I've only seen this behaviour in PHP developments.
Having constructors call initialization methods is routine, but they should still be meaningfully named, imo. I really object to init(), because it says nothing. I have no choice but to wade through code to see what it's really doing.
So, I guess I'm saying no in answer to your question; documentation isn't appropriate; the code should be clearer.
#11
Posted 25 August 2009 - 06:27 AM
auxbuss, on 25 August 2009 - 06:04 AM, said:

Surely, but that gives headaches.

In many cases in Yii, like CController, init() is an empty function only waiting to be extended. Since it serves very general purpose, it can hardly be named better. Or, does 'afterConstruct' give you more details about its goals?
#12
Posted 25 August 2009 - 06:44 AM
qiang, on 24 August 2009 - 02:45 PM, said:
Then would it not be more appropriate to model the object's life cycle (with an appropriate pattern of which I know you will be aware)?
Quote
Yes, but the way it has been implemented in Yii is that I have to ask the object something conditionally to determine its state; that's a procedural way of implementing something that oo can do for us. And that means that you have to write the code that supports and answers those questions. That's added complexity.
Quote
Yes, but my point is that you shouldn't have to check.
Quote
Ugh! It doesn't mean that, you still have to ask the object. And I have to read the code to see what init() does in each case. Double ugh!
I think we'd be better off with more use of well established patterns (namely strategy and state -- the behavioural ones); the internal use of behaviors (mixins), since we already have them and they behave a bit like strategy; more consideration of polymorphism (see strategy and state); and either null objects and/or a null behavior.
Hope that provides some food for thought.
#13
Posted 25 August 2009 - 07:17 AM
pestaa, on 25 August 2009 - 06:27 AM, said:

Indeed. If you wilfully break things, then they will be broken.
Quote
Well, on that basis you could justify an 'extend<someMethod>' method being called at the end of every method in a class. Y'know, just in case you need to extend or override something. In fact, you make my case nicely. Why have 'afterConstruct'? Because everything you do to an object once it's been instantiated is an 'afterConstruct'!

If you need to do something with an object then do it. No need to hide it in some init(). If you want to extend an object in some way then create a new subclass and in its constructor call the parent constructor and do the stuff you need. Polymorphism will take care of the rest of things.
If a object has states, which implies behavioural change, or has behavioural changes itself, then let the object manage them.
Let me try and explain what I mean. Say you have some recording device. When you switch it on, it initialises itself (constructor). All buttons are off. But, each button (action) now has a set of behaviours assigned to it (by the constructor). If you press Record nothing happens (null). If you press Stop nothing happens (null). But if you press Play, then as well as starting to do something and lighting up the button, the behaviours of the Stop and Record buttons are changed. Now, if I press Record, the machine starts to Record and the Record button lights up. And so on.
The important point is that when Record was pressed, at no time did something have to enquire as to the state of the machine.
if machineState = 'Stop' doStopStuff elseif machineState = 'Record' doRecordStuf ...
And yet the results of pressing Record each time were radically different.
I'm sure you understand.
Now, if you are not familiar with behavioural patterns, you are probably thinking: But what about states that Yii doesn't know about? Well, these patterns cover that; they are fully extensible.
More snacks and nibbles to keep you going...
#14
Posted 25 August 2009 - 07:18 AM
For the life cycle thing, in Yii, most components follow the simple one: construct -> init -> run -> desctruct. If needed, this can be subdivided into smaller cycles by init and run. I can't think of a better name than init here.
As pestaa said, init() is more like a placeholder which is empty in most cases. So the descendant classes need to document it well to tell what is done in this method. Or better, this method calls some other methods with better names.
I don't think behaviors are good here to replace init(). Behaviors are too automagical, and they incur performance degradation.
OOP doesn't mean things have to go in a twisted way. In general, I don't like most java code, because people craft code that are seemingly aesthetic but are hard or unnaturally to use (they do offer great flexibility for customization, though)
#15
Posted 25 August 2009 - 07:31 AM
whoopass, on 24 August 2009 - 06:15 PM, said:
But if someone extends the init function, they essentially overwrite the calls to make the calendar and all that. So should I just be ignoring using the init function and instead put those calls in the constructor - then make an empty init function in order for extensibility?
Yes, put everything in the constructor and let folk use the other methods to customize. They can always extend your class, override the constructor, and call parent::__construct(); at the start of it. Job done.
#16
Posted 25 August 2009 - 07:49 AM
qiang, on 25 August 2009 - 07:18 AM, said:
Yes, I mean checking state in a procedural way.
Quote
Sure. I think I've made it clear that I don't like this.
Quote
In my view, that's a symptom of the problem. You are trying to model numerous states and give them the same name. The name doesn't work because it doesn't tell you anything. This is the heart of my issue.
Quote
This has nothing to do with Java or "twisted" use of OO, though. I think that the init() idea is poor. It offers limited flexibility, but offers no feedback on what it is doing. It's also confusing. And I think it will come back to bite you, which is a shame.
Since we know that Yii objects have state, then we should model that -- which simultaneously provides extensible state, and would be very powerful -- and not represent it in a procedural way, which ultimately does result in "twisted" OO, imo.
#17
Posted 25 August 2009 - 08:01 AM
#18
Posted 25 August 2009 - 08:05 AM
I believe that the current lifecycle looks something more like construct & init -> run -> desctruct, because the first two methods are strongly coupled.
It also means there are no additional states, just more than one method deal with the first state.
Although this design decision can be reviewed and corrected, I think there are other mistakes that deserve more attention than this one.
#20
Posted 25 August 2009 - 08:11 AM
pestaa, on 25 August 2009 - 08:05 AM, said:
I believe that the current lifecycle looks something more like construct & init -> run -> desctruct, because the first two methods are strongly coupled.
It also means there are no additional states, just more than one method deal with the first state.
Although this design decision can be reviewed and corrected, I think there are other mistakes that deserve more attention than this one.
To be honest, I still don't see the problem. Perhaps I am too much into it.
No, construct and init are not tied together. As I already explained, between the two, external configurations may be applied to a constructed (yet not initialized) object.