Sembra esserci molta confusione sul modello di Inversion of Control (IoC). Un certo numero di persone lo ha identificato con il modello di strategia o un modello di componente, ma questi confronti non catturano realmente ciò che è IoC. IoC riguarda davvero come si ottiene una dipendenza. Lasciate che vi faccia un esempio:
class Game {
void Load() {
this.Sprite.Load(); // loads resource for drawing later
}
}
class Sprite {
void Load() {
FileReader reader = new FileReader("path/to/resource.gif");
// load image from file
}
}
In quanto sopra è chiaro che Sprite.Load
ha una dipendenza da a FileReader
. Quando si desidera testare il metodo è necessario quanto segue:
- Un file system in atto
- Un file di prova da caricare dal file system
- Capacità di innescare errori comuni del file system
I primi due sono ovvi, ma se vuoi assicurarti che la tua gestione degli errori funzioni come previsto, hai davvero bisogno anche del n. 3. In entrambi i casi hai potenzialmente rallentato un po 'i tuoi test in quanto ora devono andare su disco e probabilmente hai reso il tuo ambiente di test più complicato.
L'obiettivo di IoC è di disaccoppiare l'uso del comportamento dalla sua costruzione. Nota come questo differisce dal modello di strategia. Con il modello di strategia l'obiettivo è incapsulare un pezzo riutilizzabile di comportamento in modo da poterlo estendere facilmente in futuro; non ha nulla da dire su come sono costruite le strategie.
Se dovessimo riscrivere il Sprite.Load
metodo sopra, probabilmente finiremmo con:
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
Ora, abbiamo disaccoppiato la costruzione del lettore dal suo uso. Pertanto, è possibile scambiare un lettore di test durante i test. Ciò significa che l'ambiente di test non ha più bisogno di un file system, file di test e può simulare facilmente eventi di errore.
Nota che ho fatto due cose nella mia riscrittura. Ho creato un'interfaccia IReader
che ha incapsulato alcuni comportamenti, ovvero implementato il modello di strategia. Inoltre, ho spostato la responsabilità della creazione del lettore giusto in un'altra classe.
Forse non abbiamo bisogno di un nuovo nome di modello per descrivere quanto sopra. Mi colpisce come un mix di modelli di strategia e fabbrica (per contenitori IoC). Detto questo, non sono sicuro dei motivi per cui le persone si oppongono a questo modello in quanto è chiaro che risolve un problema reale e, certamente, non è ovvio per me cosa abbia a che fare con Java.