Patrones de diseño: OCP

Share

Vamos a empezar con OCP.

Un diseño inteligente del código debe tener presente los frecuentes cambios que se realizan durante el desarrollo y el mantenimiento del software. Por lo general, ocurren muchos cambios cuando se añade una nueva funcionalidad. Esos cambios en el código deberían reducirse al mínimo, ya que se asume que el código existente ya está a prueba de unidad y los cambios en el código pueden afectar a la funcionalidad existente.

El OCP (open close principle) establece que el diseño y la escritura del código deben hacerse de una forma que la nueva funcionalidad deba añadirse con un mínimo de cambios en el código existente. El diseño debe hacerse de una manera que permita la adición de nuevas funcionalidades (o nuevas clases), manteniendo en la medida de lo posible el código ya existente.

Entidades como las clases de software, módulos y funciones deberían estar abiertos a la ampliación, pero cerradas a las modificaciones.

Los programadores, aunque este principio, no lo cumplen tanto como deberían. Y si nos paramos a pensar, a muchos nos ha sucedido en algún momento. Pues bien, evitémoslo.

Ejemplo

Aquí hay un ejemplo que viola el principio. Como vemos, hay varios inconvenientes:

+ Cuando se añade una nueva forma, GraphicEditor se debe rehacer.

+ Cuando se añade una nueva forma, el desarrollador debe entender la lógica de la GraphicEditor.

+ Cuando se añade una nueva forma, se podría afectar a las funcionalidades existentes.

Además, imaginemos que GraphicEditor sea una clase enorme, con un montón de funcionalidades dentro, escrita y mantenida por una gran cantidad de desarrolladores, mientras que la forma puede ser aplicada sólo por un desarrollador. En este caso, sería una gran mejora permitir la adición de una nueva forma sin cambiar GraphicEditor.

// OCP - Mal ejemplo
 class GraphicEditor {

 	public void drawShape(Shape s) {
 		if (s.m_type==1)
 			drawRectangle(s);
 		else if (s.m_type==2)
 			drawCircle(s);
 	}
 	public void drawCircle(Circle r) {....}
 	public void drawRectangle(Rectangle r) {....}
 }

 class Shape {
 	int m_type;
 }

 class Rectangle extends Shape {
 	Rectangle() {
 		super.m_type=1;
 	}
 }

 class Circle extends Shape {
 	Circle() {
 		super.m_type=2;
 	}
 }

Aquí abajo ponemos un ejemplo que si se centra en el OCP. Utilizamos draw() como método de GraphicEditor para dibujar objetos. Utilizando el OCP los problemas del anterior diseño se evitan, porque no es GraphicEditor que cambia cuando se añade una nueva forma:

+ No se necesitan las pruebas unitarias

+ No se necesita entender GraphicEditor

+ Hay un menor riesgo de afectar a las anteriores funcionalidades cuando se añade algo.

// OCP - Buen ejemplo
 class GraphicEditor {
 	public void drawShape(Shape s) {
 		s.draw();
 	}
 }

 class Shape {
 	abstract void draw();
 }

 class Rectangle extends Shape  {
 	public void draw() {
 		// draw the rectangle
 	}
 }

Si se quisiera hacer los ejemplos con php, recomiendo que leáis: extends en php

Conclusión

Como siempre, esto es solo un principio. Hacer un diseño flexible implica más tiempo y esfuerzo, introducir un nivel de abstracción cada vez mayor aumenta la complejidad del código, por tanto, este principio debería aplicarse en las zonas que tienen más probabilidades de ser cambiadas.

Hay muchos patrones de diseño que nos ayudan a extender el código sin modificar la misma. (Decorator, Factoria, Observer, …)

Hasta aquí el OCP.
Saludos :)

Esta será la primera entrada de una serie que tengo pensada para ir traduciendo y probando algunos artículos acerca de los patrones de diseño en el desarrollo de software. En principio utilizaremos java, pero creo que pasaré los ejemplos también a php, e incluso a otros lenguajes. Haciendo así más comparativas.

Todas las estradas con el tag “patronesOO” estarán basadas principalmente en wikipedia y oodesign.

One Response to “Patrones de diseño: OCP”

  1. jorwan dice:

    Saludos, interesante. Me gustaria que ampliaras esta entrada con otro ejemplo mas, un poco mas complejo donde se aprecie igual el OCP si puedes por favor. Es solo para verlo en distintos escenarios.

    Igual, esta muy bueno.

Leave a Reply