Mis 2 centavos ...
Sí y no.
Nunca debes realmente violar los principios que adoptas; pero, sus principios siempre deben ser matizados y adoptados en servicio a un objetivo superior. Por lo tanto, con una comprensión adecuadamente condicionada, algunas violaciones aparentes pueden no ser violaciones reales del "espíritu" o "conjunto de principios".
Los principios SÓLIDOS en particular, además de requerir muchos matices, están, en última instancia, subordinados al objetivo de "entregar software funcional y de mantenimiento". Por lo tanto, adherirse a cualquier principio particular de SOLID es contraproducente y contradictorio cuando lo hace, entra en conflicto con los objetivos de SOLID. Y aquí, a menudo observo que entregar triunfa sobre mantenibilidad .
Entonces, ¿qué pasa con el D en SOLID ? Bueno, contribuye a una mayor capacidad de mantenimiento al hacer que su módulo reutilizable sea relativamente independiente de su contexto. Y podemos definir el "módulo reutilizable" como "una colección de código que planea usar en otro contexto distinto". Y eso se aplica a una sola función, clases, conjuntos de clases y programas.
Y sí, cambiar las implementaciones del registrador probablemente coloca su módulo en "otro contexto distinto".
Entonces, déjame ofrecerte mis dos grandes advertencias :
Primero: Dibujar las líneas alrededor de los bloques de código que constituyen "un módulo reutilizable" es una cuestión de juicio profesional. Y su juicio está necesariamente limitado a su experiencia .
Si no actualmente planea usar un módulo en otro contexto, es probable que esté bien para que dependa de él. La advertencia a la advertencia: sus planes probablemente estén equivocados, pero eso es también OK. Cuanto más tiempo escriba un módulo tras otro, más intuitivo y preciso será su idea de si "lo necesitaré de nuevo algún día". Pero, probablemente nunca podrá decir retrospectivamente: "He modularizado y desacoplado todo en la mayor medida posible, pero sin exceso ".
Si te sientes culpable por tus errores de juicio, confiesa y continúa ...
En segundo lugar: Invertir control no es igual a dependencias de inyección .
Esto es especialmente cierto cuando comienza a inyectar dependencias ad nauseam . La inyección de dependencia es una táctica útil para la estrategia global de la IoC. Sin embargo, yo diría que la DI es menos eficiente que otras tácticas, como el uso de interfaces y adaptadores, puntos únicos de exposición al contexto desde el módulo .
Y realmente concentrémonos en esto por un segundo. Porque, incluso si inyecta un Logger
ad nauseam , necesita escribir código en la interfaz Logger
. No podría comenzar a usar un nuevo Logger
de un proveedor diferente que toma parámetros en un orden diferente. Esa capacidad proviene de la codificación, dentro del módulo, contra una interfaz que existe dentro del módulo y que tiene un único submódulo (Adaptador) para administrar la dependencia.
Y si está codificando contra un Adaptador, si el Logger
se inyecta en ese Adaptador o si es descubierto por el Adaptador, en general es bastante insignificante para el objetivo general de mantenimiento. Y lo que es más importante, si tiene un adaptador de nivel de módulo, probablemente sea absurdo inyectarlo en cualquier cosa. Está escrito para el módulo.
tl; dr : deja de preocuparte por los principios sin tener en cuenta por qué estás usando los principios. Y, más prácticamente, simplemente cree un Adapter
para cada módulo. Use su criterio para decidir dónde dibuja los límites del "módulo". Desde dentro de cada módulo, siga adelante y consulte directamente el Adapter
. Y seguro, inyecte el registrador real en el Adapter
, pero no en cada pequeña cosa que pueda necesitarlo.