Why not "instantiate a new object inside object constructor"?

This is more a testability issue than a right/wrong thing, if you create an object on your constructor you will never be able to test your class independently.

If your class needs lots of injections on the constructor, you can allways use a factory method to inject those objects.

In this way, you will be free to mock any of those injected objects to really test your own class.

<?php

class Person {
  public $mother_language;

  // We ask for a known interface we don't mind the implementation
  function __construct(Language_Interface $mother_language) 
  {
    $this->mother_language = $mother_language
  }

  static function factory()
  {
    return new Person(new Language('English'));
  }
}

$person = Person::factory();
$person = new Person(new Language('Spanish'); // Here you are free to inject your mocked object implementing the Language_Interface

The original comment seems silly to me.

There's no reason to be afraid of classes that manage resources. Indeed, the encapsulation that classes provide is perfecty apt for this task.

If you restrict yourself to only ever pushing in resources from the outside, then what shall manage those resources? Spaghetti procedural code? Yikes!

Try to avoid believing everything you read on the internet.


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.

Tags:

Php

Oop