principalmente scende al accoppiamento di codice.
class Foo {
public function __construct() {
new Bar;
}
}
Questa coppie molto specifici Bar
a questo specifico Foo
. Non c'è modo di modificare cheBar
ottiene istanziato senza dover riscrivere il codice. Ciò significa anche che lo Foo
deve conoscere le dipendenze di Bar
. Forse oggi Bar
può essere istanziato con solo new Bar
. Ma forse domani stai refactoring Bar
e ora devi istanziarlo con new Bar($database)
. Ora devi anche riscrivere Foo
per adattarlo.
Ecco dove la dipendenza iniettabile viene fornito in (quanto sopra è non iniezione di dipendenza, non sei iniettando nulla):
class Foo {
public function __construct(Bar $bar) { }
}
Questo Foo
dichiara semplicemente che ha bisogno di un oggetto con le caratteristiche di Bar
su istanziazione. Ma Foo
non ha bisogno di sapere nulla su come Bar
avvenne per essere, quali sono le sue dipendenze sono o cosa che fa. L'unica cosa che si aspetta da Bar
è un'interfaccia definita public
, qualsiasi altra cosa è irrilevante. In effetti, per ottenere una flessibilità ancora maggiore, è possibile utilizzare uno interface
invece di una dipendenza di classe concreta qui.
Dipendenza iniezione permette di ripudiare i dettagli concreti di classi da altro codice. Ti consente di avere un luogo centrale in cui vengono istanziate le classi, che è un luogo in cui devi conoscere e considerare dettagli concreti sulle classi che stai creando. Ad esempio, questo può essere un contenitore di iniezione di dipendenza. Non vuoi diffondere la logica di istanziazione di classe dappertutto, perché come detto sopra, quella logica potrebbe cambiare, e quindi devi riscrivere il codice dappertutto.
require_once 'Foo.php';
require_once 'Bar.php';
$foo = new Foo(new Bar);
Il codice sopra è dove è stata decisa cheBar
ottiene iniettati Foo
. È anche il posto che deve preoccuparsi delle dipendenze di Bar
. Nota che il caricamento e l'istanziazione delle dipendenze sono l'unica cosa che fa questo codice. È banale modificare solo questa parte di codice, se necessario, senza dover toccare Foo
o Bar
, che potrebbe essere piena di logica aziendale complessa.
Il codice con ingerenza di dipendenza consente inoltre di separare l'app e di combinarla in modo flessibile. Ad esempio per scopi di test. O semplicemente per riutilizzare le diverse componenti in modo flessibile in diversi contesti.
Vedere anche How Not To Kill Your Testability Using Statics.
Il primo esempio è molto difficile da testare, perché non è possibile simulare Foo all'interno di Bar; il secondo si chiama Dependency Injection (DI), e ti permette di prendere in giro Foo quando stai testando Bar –
possibile duplicato di [Cos'è l'iniezione delle dipendenze?] (http://stackoverflow.com/questions/130794/what-is- dipendenza-iniezione) – Gal
Il secondo elimina anche la necessità che Foo sia in realtà un'istanza di Foo, ma gli consente di essere un Foo, o un'istanza di qualsiasi classe che estende Foo (il tipo di suggerimento che lo impone) .... accoppiamento libero , perché non sei più vincolato a un vero Foo –