Lascia che ti dia un esempio reale di questo; nomi cambiati per proteggere gli innocenti.
Stavamo integrando un Hardware Widget piuttosto costoso da un fornitore. Hanno fornito in modo utile una classe C # per l'interfaccia con il widget:
class VendorWidget
{
public void Start() { ... }
public void Turn() { ... }
public int GetPosition() { ... }
public void Stop() { ... }
... a load of other functions ...
}
Nota che questa classe ha non implementato un'interfaccia. Oltre a questo, abbiamo creato un controller per incapsulare la logica aziendale di cui avevamo bisogno. A questo punto, volevamo almeno tre diverse implementazioni del codice del widget:
- Il vero
VendorWidget
da utilizzare con l'hardware attuale.
- Un
SimulatedWidget
che abbiamo scritto in modo che gli sviluppatori che non disponevano dell'hardware effettivo potessero eseguire il maggior numero di sistemi possibile.
- Mazzi del widget per unità che testano il controller.
Con la tipizzazione strutturale, potremmo aver appena creato SimulatedWidget
e i mock per avere le stesse funzioni di VendorWidget
e portati avanti come prima. Ma poiché C # è tipicamente tipizzato, dovevamo prima creare un IWidget
con tutte le funzioni di cui avevamo bisogno:
interface IWidget
{
void Start();
void Turn();
int GetPosition();
void Stop();
... all the other functions ...
}
Quindi avvolgi una facciata banale ma noiosa intorno a VendorWidget
:
class VendorWidgetFacade : IWidget
{
private VendorWidget _underlying;
public void Start()
{
_underlying.Start();
}
public void Turn()
{
_underlying.Turn();
}
... repeat for all the other functions ...
}
e solo allora potremmo fare in modo che il controller prenda un IWidget
piuttosto che un VendorWidget
e codifichi il widget simulato e il mock.