I answered a question (link) that I used a creation of the new object in another class' constructor, here the example:
class Person { public $mother_language; function __construct(){ // just to initialize $mother_language $this->mother_language = new Language('English'); }
And I got the comment from user "Matija" (his profile) and he wrote: You should never instantiate a new object inside object consturctor, dependencies should be pushed from outside, so anyone who uses this class knows what is this class dependent on!
Generally, I can agree with this, and I understand his point of view.
However, I used to do this this way very often, for example:
ArrayAccess
interface) of objects), and this class would be used in another class, that has such a list of objects,DateTime
objects,include
(or autoload) dependant class, one should have no problem with errors,because dependant objects can be very large number, passing all of them to the class constructor can be very long and not clear, example
$color = new TColor('red'); // do we really need these lines? $vin_number = new TVinNumber('xxx'); $production_date = new TDate(...); ... $my_car = new TCar($color, $vin_number, $production_date, ...............);
as I was "born" in Pascal, then in Delphi, I have some habits from there. And in Delphi (and FreePascal as its competitor) this practice is very often. For example, there is a TStrings
class that handles array of strings, and to store them it does not use array
s but another class, TList
, that provides some useful methods, while TStrings
is only some kind of interface. The TList
object is private declared and has no access from outside but the getters and setters of the TStrings
.
Please explain me, is it really important to avoid creating objects in constructors?
I've read this discussion but have still unclear mind.
Yes it really is. You are then clear about what the object needs in order to be constructed. A large number of dependent objects being passed in is a code smell that perhaps your class is doing too much and should be broken in up in multiple smaller classes.
The main advantage of passing in dependent objects comes if you want to test your code. In your example, I cannot use a fake Language class. I have to use the actual class to test Person. I now cannot control how Language behaves to make sure that Person works correctly.
This post helps explain why this is a bad thing and the potential problems that it causes. http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
UPDATE
Testing aside, passing in dependent objects also makes your code more explicit, flexible and extensible. To quote the blog post that I linked to:
When collaborator construction is mixed with initialization, it suggests that there is only one way to configure the class, which closes off reuse opportunities that might otherwise be available.
In your example, you can only create people that have "English" as a language. But what about when you are wanting to create someone who speaks "French". I can't define that.
As for creating the objects and passing them in, that is the whole purpose of the Factory
pattern http://www.oodesign.com/factory-pattern.html. It would create the dependencies and inject them for you. So you would be able to ask it for the object that would be initialized in the manner that you want. The Person object should not have to decide what it needs to be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With