https://www.youtube.com/watch?v=DBJYKWD-xBA
Muchos problemas que surgen a los 2 o 3 años, son que vas a tener problemas a la hora de querer intercambiar implementaciones. El codigo va a estar muy acoplado a la infraestructura. Aunque es un "symbol of success" que tu empresa logro vivir todo este tiempo. Invertimos la dependencias, no dependemos de como le hablamos a la DB/mail, sino que vamos a depender de abstracciones que dicen que quiero hacer, el como no nos importa. Entonces nos desacoplamos.
- En general se dice que no sirve porque: cuando vas a cambiar la DB en prod? y es cierto, pero es solo una parte:
- En los distintos environments para distinta gente: Dev / STG / QA, va a ser mas facil intercambiar por otro filesystem o mailserver o database. Al tener el sistema modularizado es facil.
- Para unit test tambien sirve, por ej. tenes un checkout method en un ecommerce. Guardas la order, procesas la tarjeta, envias un email, si haces todo eso en 1 metodo todo muy acoplado, buena suerte haciendo Unit Testing, como mucho podrias hacer una integration testing pero necesitas toda la infraestructura. En cambio si tenes abtracciones, ej dependenes de interfaces, no hace falta usar la implementacion de pago verdadera, podes mockearla.
Fuente: Clean architecture. Cap 22. pagina 203.
Los circulos concentricos tienen que ver con detalles de implementacion de cada capa. Las interfaces estan en el circulo mas interno.
-
Los módulos de alto nivel (capas internas) nunca deben depender de módulos de bajo nivel (capas externas). (Ej, entidades, no deben depender de implementaciones service/repo) Deben depender de interfaces que estan definidas en la capa interna.
-
Los modulos de bajo nivel (Las capas externas: controllers, repositories) pueden depender de modulos de alto nivel (las internas), pero siempre a través de interfaces para lograr flexibilidad, testabilidad y desacoplamiento. Ej. una implementacion de repositorio puede depender de detalles internos, como una entidad. (pero idealmente a través de una abstraccion)
Excepciones (para sistemas pequeños): Las implementaciones concretas de esas interfaces pueden depender de detalles internos (como entidades) si las entidades son estables, pero lo ideal es depender de abstracciones para mantener un diseño limpio y escalable.
Beneficios Inversion dependencias:
-
Cambios externos, solo afectan a lo externo: Un cambio o nueva implementación en la capa externa, evita que cambios en la interna sean necesarios. Ya que usara un contrato (idealmente agnostico a detalles internos) por lo que no esta acoplado a lo interno, y no hace falta modificar capas internas. Ej. si una implementacion de Repository esta acoplado a recibir una Entidad por params, y en realidad necesito un DTO, para poder hacer testing usando mockups.
-
Conocimiento de scope de refactorizacion: Sin esta inversion de dependencias, si modifico los detalles de implementacion puedo estar rompiendo quien la use y no saberlo. Si uso un contrato, me voy a dar cuenta que voy a tener que modificarlo, por lo tanto ENTIENDO el scope de la refactorizacion, voy a entender que es un cambio de la capa interna que afecta a la externa.





