inside another one, we don't rely care what that class is exactly, only what its interface is. For example: class Car { protected $engine; public function __construct() { $this->engine = new Engine(); } public function go() { $this->engine->on(); $this->engine->applyTorque(); } }
different engines. class RaceTest() { public function testEngines() { $car1 = new Car(); $car2 = new Car(); // Uh ... } } class Car { protected $engine; public function __construct() { $this->engine = new Engine(); } public function go() { $this->engine->on(); $this->engine->applyTorque(); } }
{ protected $engine; public function __construct(IEngine $engine) { $this->engine = $engine; } public function go() { $this->engine->on(); $this->engine->applyTorque(); } }
public function testEngines() { $car1 = new Car(new V8Engine); $car2 = new Car(new LawnmowerEngine); // calls go() on each in a thread, performs timing tests, // yadda yadda don't care. :-| $test = new SpeedComparison($car1, $car2); return $test->run() ->getResult(); } } class Car { … }
its dependencies. Benefit: Flexibility. Dependencies are now based on interfaces, not specific classes. Benefit: Hey, now it's easier to unit test. ;-) ;-) :-|
what they need. I'm a programmer, Jim, not a babysitter! Tentatively suggest using defaults, eg. class Car { protected $engine; public function __construct(IEngine $engine=null) { if (is_null($engine)) { $this->engine = new Engine; } else { $this->engine = $engine; } } }