Design patterns
Iniezione di dipendenza
Ricerca…
introduzione
L'idea generale alla base di Dipendenza Iniezione è che si progetta la propria applicazione intorno a componenti liberamente accoppiati mentre si aderisce al Principio di Inversione di dipendenza. Non dipendendo da implementazioni concrete, consente di progettare sistemi altamente flessibili.
Osservazioni
L'idea alla base dell'iniezione delle dipendenze è quella di creare un codice più liberamente accoppiato. Quando una classe, invece di riannodare le proprie dipendenze, prende invece le sue dipendenze, la classe diventa più semplice da testare come unità ( test di unità ).
Per approfondire ulteriormente l'accoppiamento lento - l'idea è che le classi diventano dipendenti dalle astrazioni, piuttosto che dalle concrezioni. Se la classe A
dipende da un'altra classe concreta B
, allora non esiste un vero test di A
senza B
Mentre questo tipo di test può essere OK, non si presta al codice testabile dell'unità. Un disegno liberamente accoppiato definirebbe un'astrazione IB
(ad esempio) dalla quale la classe A
dipenderebbe. IB
può quindi essere deriso per fornire un comportamento testabile, piuttosto che basarsi sulla reale implementazione di B
per essere in grado di fornire scenari testabili ad A
Esempio strettamente accoppiato (C #):
public class A
{
public void DoStuff()
{
B b = new B();
b.Foo();
}
}
In quanto sopra, la classe A
dipende da B
Non c'è un test A
senza il cemento B
Sebbene ciò sia soddisfacente in uno scenario di test di integrazione, è difficile eseguire il test unitario A
Un'implementazione più facilmente accoppiata di quanto sopra potrebbe sembrare:
public interface IB
{
void Foo();
}
public class A
{
private readonly IB _iB;
public A(IB iB)
{
_iB = iB;
}
public void DoStuff()
{
_b.Foo();
}
}
Le due implementazioni sembrano abbastanza simili, tuttavia c'è una differenza importante. La classe A
non dipende più direttamente dalla classe B
, ora dipende da IB
. La Classe A
non ha più la responsabilità di rinnovare le proprie dipendenze: ora devono essere fornite ad A
Iniezione setter (C #)
public class Foo
{
private IBar _iBar;
public IBar iBar { set { _iBar = value; } }
public void DoStuff()
{
_iBar.DoSomething();
}
}
public interface IBar
{
void DoSomething();
}
Iniezione costruttore (C #)
public class Foo
{
private readonly IBar _iBar;
public Foo(IBar iBar)
{
_iBar = iBar;
}
public void DoStuff()
{
_bar.DoSomething();
}
}
public interface IBar
{
void DoSomething();
}