SOLID - Abierto Cerrado

El Open Closed Principle o Principio de Abierto/Cerrado establece que las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas para su extensión y cerradas para su modificación.

En términos más simples, deberíamos poder agregar funcionalidad a una entidad de software sin modificar el código fuente existente.

¿Extensión y Modificación?

Extensión: Añadir nuevas funcionalidades o comportamientos.

Modificación: Cambiar el código existente.

Las entidades de software deben diseñarse para poder agregar nuevas funcionalidades, extendiendo sus comportamientos, sin modificar el código existente. Esto reduce el riesgo de introducir errores en el código ya probado y facilita la mantenibilidad y escalabilidad del sistema.

¿Por qué es importante entonces el Open Closed Principle?

Mantenibilidad: Es más fácil mantener y añadir nuevas características sin riesgo de afectar las existentes.

Robustez: Menor probabilidad de introducir errores al modificar código antiguo.

Reusabilidad: Promueve la reutilización de código existente, facilitando la creación de nuevas funcionalidades.

Síntomas de que no se cumple

Podemos identificar cuándo no estamos respetando el Open Closed Principle:

  • Necesidad constante de modificar clases existentes al añadir nuevas características.
  • Dificultad para añadir funcionalidades sin romper el comportamiento existente.
  • Código rígido que requiere de cambios extensivos para cualquier actualización.

Ejemplo

Imagina una aplicación para el cálculo de impuestos en diferentes regiones.

Sin Open Closed Principle:

Tenemos una clase TaxCalculator que tiene un método para calcular impuestos, que funciona diferente según la región.


    public class TaxCalculator {
      public double calculateTax(Product product, String region) {
          switch (region) {
              case “Region1”:
                  // Cálculo de impuestos para la Región 1
                  break;
              case “Region2”:
                  // Cálculo de impuestos para la Región 2
                  break;
              // … más regiones
          }
          return 0.0;
      }
    }
                  

Aquí, cada vez que agregamos una nueva región o cambiar las reglas fiscales de una existente, tenemos que modificar la clase TaxCalculator.

Con Open Closed Principle:

Creamos una interfaz TaxCalculator:


    public interface TaxCalculator {
      double calculateTax(Product product);
    }
                

Y clases separadas para cada región:


    public class Region1TaxCalculator implements TaxCalculator {
      public double calculateTax(Product product) {
          // Cálculo de impuestos específico para la Región 1
          return 0.0;
      }
    }
  
    public class Region2TaxCalculator implements TaxCalculator {
      public double calculateTax(Product product) {
          // Cálculo de impuestos específico para la Región 2
          return 0.0;
      }
    }
                

Conclusiones:

Al implementar el Open Closed Principle, cada RegionTaxCalculator puede cambiarse o extenderse independientemente, sin afectar a los demás.

Esto facilita la adición de nuevas regiones y cambios en las reglas fiscales específicas de una región sin tocar el código existente.

Resumen:

El OCP impulsa un diseño de software donde los cambios son una adición más que una modificación.

Una aplicación del principio OCP hace que el código sea más robusto, fácil de mantener y seguro frente a cambios, lo que a su vez lo hace menos propenso a errores y problemas de compatibilidad.