c# Object oriented design – ¿Cómo aplicas el principio Open Closed?

Si alguna vez te has preguntado ¿Qué es el Principio Open/Closed? y ¿Cómo lo puedo implementar? te recomiendo que leas este post.
Principio OpenClosed
Principio OpenClosed


Artículos relacionados:

Este término fue introducido por Bertrand Meyer en su libro Object Oriented Software Construction de 1988. La definición de Meyer defiende la implementacion por herencia. Pero fue Martin Fowler quien popularizó este término en su libro Refactoring: Improving the Design of Existing Code de 1999. Este es el segundo de los cinco principios SOLID.

Iniciemos con esta frase obtenida del libro Object Oriented Software Construction de Bertrand Meyer:

Software Entities (Classes, Modules, Functions, ETC.) should be open for extension, but closed for modification.

Wikipedia nos dice lo siguiente:

…an entity can allow its behaviour to be extended without modifying its source code.

Este principio señala que una clase no se puede modificar, pero si se puede extender haciendo uso de la herencia. Una clase solo debe ser modificada si existe un bug, no cada vez que se necesita agregar una nueva funcionalidad porque se puede romper alguna funcionalidad existente en módulos dependientes. Para llevar a cabo este principio se hace uso de abstracciones como interfaces o clases abstractas, las nuevas funcionalidades se deben agregar creando nuevas clases que implementen estas abstracciones.

OCP- Abierto – cerrado
OCP- Abierto – cerrado
¿Sobre qué artefactos aplica este principio?
  • Funciones
  • Clases
  • Módulos
¿Qué beneficios trae el trabajar con este principio?
  • Reduce el riesgo de agregar nuevos bugs al código existente.
  • Bajo acoplamiento.
  • Flexibilidad.
  • Mantenimiento, sistemas fáciles de cambiar y evolucionar.
¿Cuándo debemos aplicar este principio?
  • Cuando se detecta que una clase será sujeta a cambio
  • Cuando no se puede cambiar una librería de terceros
¿Cuándo no debemos aplicar este principio?
  • Cuando el número de sentencias if o switch en un método no va a cambiar
  • Cuando se sabe que una clase cuenta con un comportamiento fijo.
¿Qué patrón puedo usar para aplicar este principio?
Argumentos en contra de este principio
  • Requiere más esfuerzo el diseñar las clases
  • Requiere mayor experiencia
Veamos unos ejemplos:
1. Cuando debemos usarlo:

Escenario: Tenemos una aplicación que tiene como una de sus funcionalidades el enviar notificaciones a los siguientes roles: administrador, supervisor y contador. Se necesita que el diseño soporte agregar nuevas notificaciones para la siguiente versión del sistema.

a. Solución rápida:
OCP - Clase única de notificación
OCP – Clase única de notificación

El método Enviar de la clase ServicioNotificacion decide que notificación debe enviar usando un parámetro que indica el tipo. Cuando se necesite agregar otro tipo de notificación se tendrá que modificar la clase para agregar ese nuevo requerimiento. Entonces, si seguimos trabajando de esta manera generaríamos que el diseño huela a los design smells de Opacidad y Fragilidad. Fragilidad: Al momento de hacer un cambio sobre la clase ServicioNotificacion accidentalmente se puede afectar la funcionalidad del envío de correos y ocasionaría que el código se rompa en distintas partes. Opacidad: El código de la clase ServicioNotificacion se vuelve difícil de entender debido a la cantidad de líneas que han ido aumentando con el tiempo según las nuevas notificaciones agregadas.

b. Solución propuesta:
OCP - Clases refactorizadas
OCP – Clases refactorizadas

En esta solución cada nueva notificación va en su propia clase, esta nueva clase debe heredar de ServicioNoticacion y sobre escribir el método Enviar agregando su propia lógica. Ahora el cambio de una notificación no afectará el código ya existente.

2. Cuando no debemos usarlo

Cuando las condiciones son fijas. En este ejemplo tenemos que calcular el precio de entradas para hombres y mujeres, como verán esta condición no va a cambiar:

public enum TipoSexo
{
    Masculino,
    Femenino
}

public decimal ObtenerPrecioEntrada(TipoSexo tipoSexo)
{
    decimal precioEntrada;
    switch (tipoSexo)
    {
        case TipoSexo.Femenino:
            //Codigo
            break;
        case TipoSexo.Masculino:
            //Codigo
            break;
    }
    return precioEntrada;
}
Conclusión

Uno debe ser capaz de extender el comportamiento de una clase, sin modificar su contenido. Este principio se aplica a: métodos, clases, y módulos. Como principales beneficios tenemos que nos permite crear código flexible y desacoplado. Se debe aplicar cuando se detecta que una clase será sujeta a cambio. También tiene argumentos en contra que señalan que se requiere un mayor esfuerzo y experiencia para diseñar las clases.

Referencias:
Metal Tip:

Este artículo lo escribí escuchando del DVD From wishes to eternity de la banda NightWish de Finlandia, les comparto el enlace.

Happy coding and Stay Heavy lml

Anuncios

10 comentarios en “c# Object oriented design – ¿Cómo aplicas el principio Open Closed?

  1. Esta bueno el post !! Una critica que hago para todo el ambiente del desarrollo es que me canse de ver gente que desarrolla interfaces que solo son implementadas una vez en toda la aplicacion. Las abstracciones como clases abstractas e interfaces deben ser desarrolladas con el criterio que especifica Luis.

    Me gusta

  2. Esta bueno el post !! Una critica que hago para todo el ambiente del desarrollo es que me canse de ver gente que desarrolla interfaces que solo son implementadas una vez en toda la aplicacion. Las abstracciones como clases abstractas e interfaces deben ser desarrolladas con el criterio que especifica Luis.

    Le gusta a 1 persona

    1. Hola Christian, es cierto lo que comentas yo también he observado que hay una mala costumbre de definir interfaces que no son reutilizadas, solo sirven para un caso puntual; ademas, que son interfaces grandes con muchas funcionalidades que tampoco facilitan su implementacion. Pero también debo decir que todo eso ocurre por desconocimiento, ya que no se tienen los conceptos claros. Se cree que por trabajar con interfaces, como sea que estén mal diseñadas, ya se esta haciendo lo correcto, Espero que con la serie de post acerca de los principios SOLID ayude a tener claro esos conceptos :).
      Saludos

      Le gusta a 1 persona

      1. Un escenario clasico de mala implementacion es cuando se construyen repositorios. Creo que mucha gente confunde el patron IRepository con IoC (Inversion of Control).

        Me gusta

    1. Hola, en la fase de desarrollo debe haber alguien que se encargue de hacer la revisión del código. Si una clase esta mal hecha se debe refactorizar o volver a escribir. Si no hay una persona que se encargue de esa actividad el equipo debe ser responsable en buscar recursos, como este blog ;), para conocer las técnicas y principios de diseño que existen actualmente para aplicar en su desarrollo.
      Saludos

      Me gusta

  3. Correccion Ami comentario anterior
    Tambien hay que ser claros con la nomenclatura de Clases,Metodos e Interfaces etc. ya que estas deben de ser intuitivas y de manera standarizadas (
    ej. las funciones privadas y variables las nombro con el guion bajo al inicio, solo para distinguir que se trata de objetos privados.
    ) y no crear demasiadas dependecias entre si.
    Me a tocado Debugear codigo asi y es toda una telaraña de codigo que se anidan objetos entre si. U.U

    Le gusta a 1 persona

    1. Hola Oscar, el código debe ser claro e intuitivo, la mejor documentación es la que no se necesita :). Ademas, se deben crear clases con responsabilidades especificas para cuidar el acoplamiento y la cohesión.
      Saludos

      Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s