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

  1. Existen ciertas sutilezas que deben considerarse antes de declarar que el diseño respeta este principio, El dilema circulo/elipse
  2. 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.