Supongamos que tenemos 1001 clientes que construyen sus dependencias directamente en lugar de aceptar inyecciones. Refactorizar el 1001 no es una opción de acuerdo con nuestro jefe. En realidad, ni siquiera se nos permite acceder a su fuente, solo a los archivos de clase.
Lo que se supone que debemos hacer es "modernizar" el sistema por el que pasan estos 1001 clientes. Podemos refactorizar que a todos nos gusta. Las dependencias son parte de ese sistema. Y algunas de esas dependencias se supone que debemos cambiar para tener una nueva implementación.
Lo que nos gustaría hacer es tener la capacidad de configurar diferentes implementaciones de dependencias para satisfacer esta multitud de clientes. Lamentablemente, DI no parece ser una opción ya que los clientes no aceptan inyecciones con constructores o configuradores.
Las opciones:
1) Refactoriza la implementación del servicio que los clientes usan para que haga lo que los clientes necesitan ahora. Bang, hemos terminado. No es flexible. No es complejo.
2) Refactorice la implementación para que delegue su trabajo en otra dependencia que adquiera a través de una fábrica. Ahora podemos controlar qué implementación usan todos al refactorizar la fábrica.
3) Refactorice la implementación para que delegue su trabajo en otra dependencia que adquiera a través de un localizador de servicios. Ahora podemos controlar qué implementación utilizan todos configurando el localizador de servicios que podría ser simplemente un hashmap
de cadenas a objetos con un poco de conversión en curso.
4) Algo en lo que ni siquiera he pensado todavía.
El objetivo:
Minimice el daño de diseño causado por arrastrar el viejo código de cliente mal diseñado hacia el futuro sin agregar complejidad inútil.
Los clientes no deben saber ni controlar la implementación de sus dependencias, pero insisten en construirlos con new
. No podemos controlar el new
pero sí controlamos la clase que están construyendo.
Mi pregunta:
¿Qué no he considerado?
¿Realmente necesitas una posibilidad de configurar entre diferentes implementaciones? ¿Para qué propósito?
Agilidad. Muchas incógnitas. La gerencia quiere potencial para el cambio. Sólo perder la dependencia del mundo exterior. También pruebas.
¿necesita una mecánica de tiempo de ejecución, o simplemente una mecánica de tiempo de compilación para cambiar entre diferentes implementaciones? ¿Por qué?
Es probable que la mecánica de tiempo de compilación sea suficiente. A excepción de las pruebas.
¿Qué granularidad necesita para cambiar entre las implementaciones? ¿De repente? Por módulo (cada uno contiene un grupo de clases)? ¿Por clase?
De los 1001 solo uno se ejecuta a través del sistema a la vez. Cambiar lo que todos los clientes usan a la vez es probable que esté bien. Sin embargo, el control individual de las dependencias es importante.
¿Quién necesita controlar el interruptor? ¿Solo tu / tu equipo de desarrolladores? ¿Un administrador? ¿Cada cliente por su cuenta? ¿O los desarrolladores de mantenimiento para el código del cliente? Entonces, ¿qué tan fácil / robusto / infalible debe ser la mecánica?
Dev para pruebas. Administrador a medida que cambian las dependencias del hardware externo. Debe ser fácil de probar y configurar.
Nuestro objetivo es mostrar que el sistema se puede rehacer rápidamente y modernizar.
caso de uso real para el cambio de implementación?
Uno es que el software proporcionará algunos datos hasta que la solución de hardware esté lista.