Digamos que tenemos 1001 clientes que construyen sus dependencias directamente en lugar de aceptar inyecciones. Refactorizar el 1001 no es una opción según 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 todo lo que queramos. Las dependencias son parte de ese sistema. Y algunas de esas dependencias que 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 a esta multitud de clientes. Lamentablemente, DI no parece una opción ya que los clientes no aceptan inyecciones con constructores o setters.
Las opciones:
1) Refactorice la implementación del servicio que usan los clientes 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 a otra dependencia que adquiera a través de una fábrica. Ahora podemos controlar qué implementación utilizan todos refactorizando la fábrica.
3) Refactorice la implementación para que delegue su trabajo a 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 una hashmap
cadena de objetos con una pequeña conversión.
4) Algo en lo que ni siquiera he pensado todavía.
El objetivo:
Minimice el daño de diseño causado por arrastrar el antiguo código de cliente mal diseñado al futuro sin agregar una complejidad sin sentido.
Los clientes no deben conocer o controlar la implementación de sus dependencias, pero insisten en construirlas new
. No podemos controlar el, new
pero controlamos la clase que están construyendo.
Mi pregunta:
¿Qué he dejado de considerar?
¿realmente necesita una posibilidad de configurar entre diferentes implementaciones? ¿Con qué propósito?
Agilidad. Muchas incógnitas. La gerencia quiere potencial para el cambio. Solo pierde la dependencia del mundo exterior. También probando.
¿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é?
La mecánica del tiempo de compilación es bastante probable. Excepto por las pruebas.
¿Qué granularidad necesita para cambiar entre 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 en cualquier momento. Cambiar lo que todos los clientes usan a la vez probablemente esté bien. Sin embargo, el control individual de las dependencias es probablemente 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 / robusta / infalible necesita ser la mecánica?
Desarrollador para pruebas. Administrador a medida que cambian las dependencias de hardware externo. Debe ser fácil de probar y configurar.
Nuestro objetivo es mostrar que el sistema puede rehacerse rápidamente y modernizarse.
caso de uso real para el interruptor de implementación?
Una es que el software proporcionará algunos datos hasta que la solución de hardware esté lista.