Principios SOLID y Estrategias de Diseño Orientado a Objetos

Enviado por federzzz y clasificado en Informática y Telecomunicaciones

Escrito el en español con un tamaño de 4,75 KB

Principios SOLID: Fundamentos del Diseño Orientado a Objetos

Los principios SOLID son un conjunto de cinco principios de diseño de software destinados a hacer que los diseños de software sean más comprensibles, flexibles y mantenibles.

  1. Principio de Única Responsabilidad (SRP): Una clase debería concentrarse solo en hacer una cosa, de tal forma que cuando cambie algún requisito, dicho cambio solo afecte a esa clase por una razón.

  2. Principio Abierto/Cerrado (OCP): Cambia el comportamiento de una clase mediante herencia, polimorfismo y composición. Anticípate al cambio: prepara tu código para que los posibles cambios en el comportamiento de una clase se puedan implementar mediante herencia y composición.

  3. Principio de Sustitución de Liskov (LSP): Las subclases deben comportarse adecuadamente cuando sean usadas en lugar de sus clases base.

  4. Principio de Segregación de Interfaces (ISP): Mantén las interfaces pequeñas y cohesivas, que puedan coexistir unas con otras.

  5. Principio de Inversión de Dependencias (DIP): Para conseguir robustez, flexibilidad y posibilitar la reutilización, haz que tu código dependa de abstracciones y no de concreciones. Esto implica utilizar muchas interfaces y clases abstractas y, sobre todo, exponer las dependencias que una clase pueda tener (por constructor o por parámetros).

Programación hacia la Interfaz y Abstracción

Programar hacia la interfaz es centrar la atención en lo que hace cada objeto, de manera que cuando un objeto necesita un servicio particular, se delega la responsabilidad a cualquier objeto que brinde el servicio (a través de la interfaz). Así, no estamos “atados” a una implementación específica, sino que se delega al objeto que implementa la operación de la manera más adecuada.

Buenas Prácticas de Abstracción

  • No hay que declarar variables de clases concretas, sino abstractas.
  • Los patrones de creación permiten que un sistema esté basado en términos de interfaces y no en implementaciones.
  • Hay que favorecer la reutilización y fomentar la delegación.
  • Favorecer la composición sobre la herencia de clases.
  • Los diseños suelen ser más reutilizables si dependen de la composición.
  • Ayuda a mantener cada clase encapsulada y centrada en una sola tarea.
  • Herencia y composición trabajan juntas.

Mecanismos de Reutilización y Relación de Clases

Herencia

Características: Es reúso de caja blanca. Esto quiere decir que hereda clases que no se trasladan a objeto.

Ventaja: Se define estáticamente en tiempo de compilación y es sencilla de usar (permitido directamente por el lenguaje de programación). También facilita modificar la implementación que está siendo utilizada.

Desventaja:

  • No se pueden cambiar las implementaciones heredadas de las clases padre en tiempo de ejecución.
  • Debido a que la herencia se define en tiempo de compilación, las clases padre suelen definir al menos parte de la representación física de sus subclases.
  • La herencia “rompe el encapsulamiento”.

Realización (Implementación de Interfaces)

Características: Se utiliza para relacionar una clase con una interfaz.

Ventaja: Los clientes no tienen que conocer los tipos específicos de los objetos que usan; basta con que se adhieran a la interfaz que esperan. Los clientes desconocen las clases que implementan dichos objetos, solo conocen las clases abstractas que definen la interfaz.

Composición

Características: Es un tipo de relación todo-parte en donde el conjunto se compone de muchas partes. Es reúso de caja negra, debido a que permite la delegación (hacer peticiones, delegando responsabilidad a otra clase sin romper el encapsulamiento).

Ventaja:

  • Se define dinámicamente en tiempo de ejecución a través de objetos que tienen referencias a otros objetos.
  • Se accede solamente a través de sus interfaces.
  • Cualquier objeto puede ser reemplazado en tiempo de ejecución por otro, siempre que sean del mismo tipo.
  • Como la implementación de un objeto se escribe en términos de interfaces de objetos, las dependencias de implementación son notablemente menores.

Entradas relacionadas: