En el primer artículo de esta serie hice un breve paseo por los síntomas de un mal diseño de software, en el presente artículo me gustaría discutir sobre los principios de diseño de clases.
SRP :: Single Responsability Principle
Una clase debe tener una sola responsabilidad y una sola funcionalidad de la cual hacerse cargo
No debe haber nunca más de una razón para que una clase cambie
OCP :: Open Closed Principle
Probablemente el más importante de todos los principios.
Debemos diseñar e implementar nuestros modulos de forma que sean facilmente extendibles sin requerir que sean modificados, la clave para lograrlo es la abstracción
LSP :: Liskov Substitution Patter
Las clases derivadas deben ser substituibles por sus clases padres
No voy a ahondar mucho en este tema (pueden referirse a la gran selección de artículos en objectmentor.com) sin embargo creo importante resaltar ciertos puntos
- Existen ciertas sutilezas que deben considerarse antes de declarar que el diseño respeta este principio, El dilema circulo/elipse
- Diseña por contrato, es decir que el contrato de la clase padre debe ser respetado por la clase derivada, para lo que:
- Las precondiciones del método derivado no deben ser mayores que las de aquel de la clase padre
- Las postcondiciones del método derivado no deben ser inferiores que las de aquel de la clase padre
Las violaciones de este principio son violaciones al primer principio por extensión.
DIP :: Dependency Inversion Principle
La dependencia debe ser hacia las abstracciones y no hacia las implementaciones
Hay un motivo detrás de esto. Las clases abstractas o las interfaces varían muy poco en comparación a las clases concretas, lo que a su vez repercute sobre el primer principio porque son estas abstracciones las que se deben aprovechar para extender en lugar de modificarlas.
ISP :: Interface Segregation Principle
Muchas interfaces específicas son mejores que una única interfaz generica
Se debe tener en cuenta que es absurdo considerar una interfaz específica por cada clase que lo requiera, lo aconsejable es categorizar las funcionalidades por tipo de forma que se las pueda agrupar en interfaces especializadas.
En el próximo artículo se va a hacer una pequeña revisión sobre los principios de la arquitectura de paquetes, ya que la sola aplicación de los principios de diseño de clases no asegura un diseño y una arquitectura de software adecuada.