Parece haber mucha confusión sobre el patrón de Inversión de Control (IoC). Varias personas lo han equiparado con el Patrón de estrategia o un Modelo de componentes, pero esta comparación realmente no capta de qué se trata IoC. IoC realmente trata sobre cómo se obtiene una dependencia. Dejame darte un ejemplo:
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
}
}
En lo anterior está claro que Sprite.Load
tiene una dependencia de a FileReader
. Cuando desee probar el método, necesita lo siguiente:
- Un sistema de archivos en su lugar
- Un archivo de prueba para cargar desde el sistema de archivos
- Capacidad para desencadenar errores comunes del sistema de archivos
Los dos primeros son obvios, pero si desea asegurarse de que su manejo de errores funcione como se espera, realmente también necesita el n. ° 3. En ambos casos, posiblemente haya ralentizado sus pruebas un poco, ya que ahora deben ir al disco y probablemente haya complicado su entorno de prueba.
El objetivo de IoC es desacoplar el uso del comportamiento de su construcción. Observe cómo esto difiere del patrón de Estrategia. Con el patrón de estrategia, el objetivo es encapsular una parte de comportamiento reutilizable para que pueda ampliarla fácilmente en el futuro; No tiene nada que decir sobre cómo se construyen las estrategias.
Si tuviéramos que reescribir el Sprite.Load
método anterior, probablemente terminaríamos con:
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
Ahora, hemos desacoplado la construcción del lector de su uso. Por lo tanto, es posible intercambiar un lector de prueba durante la prueba. Esto significa que su entorno de prueba ya no necesita un sistema de archivos, archivos de prueba y puede simular fácilmente eventos de error.
Tenga en cuenta que hice dos cosas en mi reescritura. Creé una interfaz IReader
que encapsulaba algún comportamiento, es decir, implementé el patrón de Estrategia. Además, trasladé la responsabilidad de crear el lector adecuado a otra clase.
Tal vez no necesitamos un nuevo nombre de patrón para describir lo anterior. Me parece una combinación de los patrones de Estrategia y Fábrica (para contenedores IoC). Dicho esto, no estoy seguro de por qué las personas se oponen a este patrón, ya que está claro que resuelve un problema real y, ciertamente, no es obvio para mí lo que esto tiene que ver con Java.