Interface segregación - ProgOrientadaObjetos-P-AA2021/consulta-2bim-rennypomx GitHub Wiki

El Principio de Segregación de Interfaces

El Principio de Segregación de Interfaces fue utilizado por primera vez por Robert C. Martin durante unas sesiones de consultoría en Xerox. Por aquella época, Xerox estaba diseñando una impresora multifuncional. El software diseñado para la impresora funcionaba y se adaptaba perfectamente a las necesidades iniciales de la impresora; sin embargo, conforme fue evolucionando, y por lo tanto cambiando, se hizo cada vez más difícil de mantener. Cualquier modificación tenía un gran impacto global sobre el sistema. Los clientes no deben ser forzosamente dependientes de las interfaces que no utilizan. El principio de segregación de interfaces viene a decir que ninguna clase debería depender de métodos que no usa. Por tanto, cuando creemos interfaces que definan comportamientos, es importante estar seguros de que todas las clases que implementen esas interfaces vayan a necesitar y ser capaces de agregar comportamientos a todos los métodos. En caso contrario, es mejor tener varias interfaces más pequeñas. Las interfaces nos ayudan a desacoplar módulos entre sí. Esto es así porque si tenemos una interfaz que explica el comportamiento que el módulo espera para comunicarse con otros módulos, nosotros siempre podremos crear una clase que lo implemente de modo que cumpla las condiciones. El módulo que describe la interfaz no tiene que saber nada sobre nuestro código y, sin embargo, nosotros podemos trabajar con él sin problemas.


EJEMPLO:

Imagina que tienes una tienda de CDs de música, y que tienes modelados tus productos de esta manera:

El producto tiene una serie de propiedades que nuestra clase CD sobrescribirá de algún modo. Pero ahora has decidido ampliar mercado, y empezar a vender DVDs también. El problema es que para los DVDs necesitas almacenar también la clasificación por edades, porque tienes que asegurarte de que no vendes películas no adecuadas según la edad del cliente. Lo más directo sería simplemente añadir la nueva propiedad a la interfaz:

¿Qué ocurre ahora con los CDs? Que se ven obligados a implementar recommendedAge, pero no van a saber qué hacer con ello, así que lanzarán una > excepción:

Con todos los problemas asociados que hemos visto antes. Además, se forma una dependencia muy fea, en la que cada vez que añadimos algo a Product, nos vemos obligados a modificar CD con cosas que no necesita. Podríamos hacer algo tal que así:

Y hacer que nuestras clases extiendan de aquí. Esto solucionaría el problema a corto plazo, pero hay algunas cosas que pueden seguir sin funcionar demasiado bien. Por ejemplo, si hay otro producto que necesite categorización por edades, necesitaremos repetir parte de esta interfaz. Además, esto no nos permitiría realizar operaciones comunes a productos que tengan esta característica. La alternativa es segregar las interfaces, y que cada clase utilice las que necesite. Tendríamos por tanto una interfaz nueva:

Y ahora nuestra clase DVD implementará las dos interfaces:

La ventaja de esta solución es que ahora podemos tener código AgeAware, y todas las clases que implementen esta interfaz podrían participar en código común. Imagina que no vendes sólo productos, sino también actividades, que necesitarían una interfaz diferente. Estas actividades también podrían implementar la interfaz AgeAware, y podríamos tener código como el siguiente, independientemente del tipo de producto o servicio que vendamos:

Bibliografia:

https://desarrolloweb.com/articulos/principio-de-segregacion-interfaces-dotnet.html

https://es.wikipedia.org/wiki/Principio_de_segregaci%C3%B3n_de_la_interfaz

https://devexperto.com/principio-de-segregacion-de-interfaces/