El principio SOLID de Open Closed:
El patrón Strategy
Estoy empezando a estudiar patrones de programación, y voy a realizar unos cuantos actículos para ver como se pueden aplicar usando el lenguaje Gambas3. Intento poner lo que pienso y lo que he entendido.
La mayoría de los ejemplos que he encontrado, están realizados en lenguajes como JAVA, C++, PYTHON, etc... aquí lo que voy a intentar es convertirlos a Gambas3, para así entenderlos mejor.
Intentaré dejar siempre las referencias tantos a blog como a libros donde he sacado los ejemplos, documentación, etc...
¿que son patrones de diseño ?
Estudiando un gran número de problemas, se observó que muchos tenían formas parecidas de resolverse, y que se podían agrupar unas serie de problemas con una forma de solucionarlo. De esa manea, esta "formas de solucionarlo", los patrones, los podíamos usar de "herramienta" para que aplicándolos, resolver nuevos problemas.
Los patrones de diseño son la base para la búsqueda de soluciones a problemas comunes en el desarrollo de software y otros ámbitos referentes al diseño de interacción o interfaces.
¿como se crean estos patrones?
A groso modo, se crean varias clases, que entre ellas se van a conectarse para pasarse la información de una determinada manera. (se pasan valores que ¡¡incluso sin objetos de otras clases!!! se pueden pasar como información (veasen los distintos esquemas que se presentar de cada patrón ). Para ello usamos las propiedades y métodos de las clases. Y luego instanciaremos objetos de esas clases para usarlos en la programación.
Nota:
La Programación Orientada a Objetos se basa en el uso de las clases y objetos.
Clase: es una plantilla donde podemos crear ("instanciar") muchos objetos. Es como si fuera un molde
Objetos: Usando las clases ("molde") podemos crear ("instanciar") los objetos, que son los que usaremos en la programación.
Ejemplo:
Tenemos una pastelería, donde existen diversos moldes ("Clases") para hacer los pasteles. Los moldes (en forma de estrella, circular, rectangular, etc),los usaremos para crear ("instanciar") los distintos pasteles (los "objetos"). Al final del dia tendremos varios pasteles de difersas formas creados.
A continuación (y en más entradas de este blog), veremos la explicación de los principales patrones adaptandolos a Gambas3.
El patrón Strategy:
Los principios de SOLID de Open Closed:- Principio de responsabilidad única: crear pequeñas clases que contienen un algoritmo muy comcreto.Para resolver un problema, siempre existen varias formas de hacerlo.¿cual elegir?
- Nuestro código debería estar abierto a la extensión, pero cerrado a la modificación. Es decir, que para añadir una nueva funcionalidad, no tengamos la necesidad de modificar los algoritmos que ya están programados. Es aquí es donde el patrón strategy cobra su importancia.
Patrón strategy, es una alternativa al uso de bloques "switch" (select case) , que permite:
- Que sea fácil mantener y ampliar nuevas funcionalidades
- Fácil lectura del codigo
Se trata de hacer un programa que simule la variedad de comportamientos que tienes los patos a la hora de volar. Por ejemplo: hay algunos que no vuelan, otros que planean, y otros que vuelan bien (usan sus alas para volar e impulsarse). Este problema es muy sencillo, y se podía realizar mediante una expresión tipo:
- La desventaja de este método es que cuando son algoritmos largos (en vez de ser una sola linea "print"), y sobre todo cuando se quiere aumentar las opciones, rompemos la regla de Solid De Open Closed.
A continuación vemos como se puede hacer usando el patrón Strategy, con la ventaja de que cuando se amplia una opción (o varias), simplemente se va creando una nueva clase. Esto, aunque a primera vista, parezca que es más código y más complejo que el usar "Select Case", el usarlo tiene la ventaja de cuando tengamos muchas opciones y más complejidad en los algoritmos, sea facilite comprender el código, de mantenerlo y de ampliarlo en el futuro.
Esquemas: Patrón Strategy |
Empezamos:
Viendo caso, viendo el esquema general, lo adaptamos a nuestro problema:
A partir de este esquema vamos a crear las clases en el proyecto:
Y empezamos a codificar las clases:
Clase IVolar:
Clase NoVolar:
Clase VolarAlas:
Clase VolarPlaneando:
-
Clase Pato:
-
Y ahora vamos a usar estas clases y este patrón
0) Creamos un formulario con un labeltext.
1) Cuando se abra el formulario vamos a:
2) Crear un objeto de la clase pato, que pueda Volar
3) Luego ese mismo objeto, le vamos a cambiar el estado (como si lo hubiesemos herido), y nos lo mostrará:
Captura de lo que muestra la aplicación:
Ya habéis observado como se hace para indicar al objeto "p" cual es su comportamiento, incluso lo sencillo que resulta cambiar su comportamiento (lo han herido, y ya no puede volar).
Ahora imaginaos que nos piden que incluyamos dos nuevos comportamientos:
- Que vuele, pero con un cohete
- Que vuele, pero dentro de un avión
¿como lo haríamos? Simplemente añadiríamos dos nuevas clases (que heredarían de la clase IVolar) y ya tendríamos dispuesto los nuevos comportamientos para usarlo en el programa.... como habéis observado, no he cambiado nada de las clases ni de los algoritmos que hemos hecho anteriormente (si lo hubiesemos hecho con Select Case, si tendríamos que "retocar" parte del codigo), ahora solo tenemos que "añadir" clases sin tocar nada de lo anterior.!!!
Os dejo el ejemplo completo en este enlace: descarga en box.com
Otro Ejemplo: Clases de patos que tengan predefinido su comportamiento ante el vuelo.
¿como lo hacemos? Creando clases heredadas de la clase Pato, y usando el constructor, donde definimos su comportamiento inicial.
Este comportamiento (como en el ejemplo anterior), podrá ser modificado por el programa dinamicamente.
El esquema del proyecto sería:
Y el código solo hay que añadir las clases PatoGordo, PatoHule y PatoRedBlue, para tenerlos disponible (el resto de clases Pato, Ivolar, NoVolar, VolarAlas, y VolarPlaneando, no hace falta tocarlas ni añadir nada).
El código de las clase: PatoGordo
-
La Clase PatoHuel
-
La Clase PatoRedBlue
-
¿como usar estas nuevas clases?
Vamos a crear una 3 patos de las distintas clases de patos, y al ultimo le cambiamos su comportamiento inicial, porque ha tenido un accidente...
Captura de la salida del programa:
Como veis, hemos conseguido tener varias clases de patos con distintos tipos de comportamiento ante el vuelo, y además, hemos podido cambiar su comportamiento fácilmente.
Notas:
Super: Hace referencia al objeto del que hereda. Asi podemos acceder a métodos y propiedades que estan definidas en el objeto "padre". http://gambasdoc.org/help/lang/super?es
Function tipopato(p As Pato) As String: Esta funcion nos devuelve el nombre del objeto que le pasamos. Como veis el parametro es indicado del tipo "as Pato", pero este parámetro también acepta objetos de clases que heredan de Pato (PatoGordo,PatoHule y PatoRedBlue)
Enlace de descarga del código fuente: enlace
Fuentes:
Blogs:
http://programandonet.com/web/patrones-de-diseno-strategy/
http://marcestarlet-code.
https://github.com/
Libros:
head_first_design_pattern
Nota:
Siguiente entrada sobre patrones: Patrón Observer: la estación meteorológica (new)