I know some OOP and have read this and that, but am not a hardcore OOP guy and have no formal training and can't rattle off why something should use dependency injection or not, and may not be able to identify all dependencies in a design, hence my question.
Answering a question here on SO (Using a object in methods of other objects) I started to doubt myself. As far as dependencies, is one of these better or worse or both acceptable? Any design limitations?
I have read and understand both but haven't ever come across a comparison. Why would one be better used in a design, etc.
Dependency Injection:
class myClass {
private $db;
public function __construct($db) {
$this->db = $db;
}
}
Registry (maybe also something else):
class myClass {
private $db;
public function __construct() {
$this->db = Registry::get('db');
}
}
A dependency injection is required because the object needs certain data to perform its functions correctly.
Dependency Injection can be performed in three different ways:
Whenever you do any of these, you are already doing dependency injection:
Constructor injection
Public property injection
Both methods are possible implementations of dependency injection. Basically dependency injection means to define a way to configure (inject) the classes to be used at runtime in order to make to code more flexible compared to using using hard coded class names and constructors in the code. Dependency injection follows a principle called
inversion of control
.This is especially interesting for testing code but can be used in a variety of other scenarios where you want to make an application flexible and maintainable.
While dependency injection mostly is referred to as
DI container
, it can generally be done using a couple of different methods - which may also coexist. Here comes an (incomplete) list:It has a lot to do with testability.
In your example, the first (Dependency Injection) is better. The reason it's better is because it accepts
db
as an argument, which means this is testable, you can use a mockdb
for testing and testmyClass
does the right thing with it.The second example (Registry) is not recommended as not only
myClass
depends ondb
, it now also depends onRegistry
, and the worst part it's that it knows how to get adb
. It's too smart, it should be dumb like the first one, dumb things are more testable, smart things are not.