Dedicado a mis proyectos en Gambas ,un lenguaje de programación parecido al Visual Basic + Java pero ampliamente mejorado y...¡¡para gnu/linux!!.La potencia del gnu/linux sumada a la facilidad del Basic



Consultas, Desarrollo de programas y petición de presupuestos:



Mostrando entradas con la etiqueta patrones. Mostrar todas las entradas
Mostrando entradas con la etiqueta patrones. Mostrar todas las entradas

domingo, 19 de enero de 2014

Combinar Patrones de Diseño: Ejemplo de aplicación de varios patrones de diseño en un mismo programa: Command y Strategy

Combinar Patrones de Diseño

Ejemplo de aplicación de varios patrones de diseño  (Command y Strategy) en un mismo programa: Organizador de Descargas 

versión 0.0.3




Ayer os en traje un programa para organizar la carpeta de descarga, internamente usaba el patrón Command, para ejecutar las ordenes de las reglas (mover, copiar o borrar).

En el módulo "AplicarComandos", usaba una orden Select Case para, según que orden, crear el comando correspondiente y luego ejecutarlo en una lista:



Bien, este diseño (el uso del Select Case), tiene el siguiente problema:

  • A medida que vayamos a añadir más órdenes ("Comprimir", "Crear Accesos Directos en el Escritorio", etc), vamos a tener que retocar él codigo en esa zona. Rompiendo uno de los principios la programación "SOLID de Open Closed": 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.El Patrón strategy, es una alternativa al uso de bloques "switch" ( select case) ya que permite:
  • Que sea fácil mantener y ampliar nuevas funcionalidades
  • Fácil lectura del código

Vamos a aplicar el siguiente esquema, para convertir el Switch (Select Case) del programa al patrón Strategy:

Esta serán nuestras nuevas clases:
Clase InterfaceCrearComando (GuardeStrategy en el esquema):
->

Clase EstrategiaBorrar: (seria la GuardedStrategyA)
->

Clase EstrategiaCopiar:(seria la GuardedStrategyA)
->

Clase EstrategiaMover:(seria la GuardedStrategyA)
->

SwitchStrategyCrearComando:
->

Y ahora en el módulo AplicarComando, habria que hacer 3 cambios:
Añadir una instancia privada de la clase SwitchStrategyCrearComando
->

Añadir una subrutina donde añadiremos las estrategias que existen (estrategiaCopia, estrategiaMover y estrategiaBorrar)
->

Y la zona del select case se sustituye por esta:
->

El resultado de la ejecución del programa es el mismo, pero para realizar futuras ampliaciones ahora resulta mucho más sencillo:




Para añadir un nuevo comando, por ejemplo se haría asi:
1) Crear la nueva clase que hereda de Comando, por ejemplo "Descomprimir", donde definimos su método ejecutar()
2) Crear una nueva clase EstrategiaDescomprimir, donde definimos las propiedades del comando
3) Añadir  en la subrutina GenerarListaEstrategiasCrearComandoDisponibles(), la nueva estrategia:
Dim estrategiaDescomprimirtmp as new EstrategiaDescomprimir
...
SelectorEstrategias.add(EstrategiaDescomprimir)

Y para que el usuario la vea en el formulario, en el Fmain, añadimos al combobox la nueva orden mediante el método add:
ComboBoxAccion.Add(("Deescomprimir"))

Y ya la tenedriamos añadida.

Saludos

Enlace de descarga del archivo de instalación .deb: http://clasificaryordenar.blogspot.com.es/
Enlace de descarga del código fuente: enlace version 0.0.3 (en el blog de clasificaryordenar se puede ver el codigo fuente de la última version)


Nota:
23/01/2014: He realizado un pequeño blog donde esta la información completa del programa y las ultima revisión 0.0.5 http://clasificaryordenar.blogspot.com.es/


Fuentes:
http://www.cin.ufpe.br/~sugarloafplop/final_articles/02_SwitchStrategy%20_Spanish_.pdf
http://programandonet.com/web/patrones-de-diseno-strategy/

sábado, 4 de enero de 2014

Esquema de Relaciones entre Patrones de Diseño

Esquema de Relaciones 

entre Patrones de Diseño


En las anteriores entradas (vease al final de este post, para ver el listado de las entradas), os he dejado ejemplos de uso de patrones de diseño en Gambas3. Si comparais entre los distintos patrones, podéis ver que hay ciertas similitudes entre ellos, realmente algunos son casos especiales de otros. 

En el siguiente esquema podeis ver como se relacionan los distintos patrones:



También existe una clasificación de los patrones:



Os dejo tambien el esquema de los patrones "gof" para tenerlo de hoja de referencia en formato pdf:




Aqui teneis  las distintas entradas y enlaces a los post de los ejemplos de patrones aplicados al lenguaje de programación Gambas3:

 



Patrones de Diseño



Nombre Ejemplo Enlace
Creacionales
Singleton Creando Log http://jsbsan.blogspot.com.es/2013/12/patron-singleton-ejemplo-creando-log.html
Builder Fabricar vehiculos de marca determinada. http://jsbsan.blogspot.com.es/2013/11/patron-builder-ejemplo-creando-coches.html
Prototype tipos de Tv http://jsbsan.blogspot.com.es/2014/01/patron-prototype-ejemplo-tipos-de.html
Abstract Factory La fabrica de vehiculos http://jsbsan.blogspot.com.es/2013/10/patron-abstract-factory-la-fabrica-de.html
Factory Method




Estructurales
Adapter Tipos de Motor http://jsbsan.blogspot.com.es/2013/12/patron-adaptador-ejemplo-tipos-de-motor.html
Decorador Cafés y Condimentos: recursividad http://jsbsan.blogspot.com.es/2013/10/patron-decorador-cafes-y-condimentos.html
Bridge Dibujando punteado y normal http://jsbsan.blogspot.com.es/2013/12/patron-bridge-ejemplo-dibujando.html
Composite Cálculo de gasto de sueldos mensuales http://jsbsan.blogspot.com.es/2013/11/patron-composite-ejemplos-calculo-de.html
Flyweight Formatos de tipo de letra y tamaño http://jsbsan.blogspot.com.es/2014/01/patron-flyweight-ejemplo-formatos-de.html
Facade Inmobiliaria: Clientes y departamentos http://jsbsan.blogspot.com.es/2013/11/patron-facade-fachada-ejemplo-de.html
Proxy Realizar un control de acceso a recursos y/o partes del programa http://jsbsan.blogspot.com.es/2013/12/patron-proxy-ejemplo-realizar-un.html
Delegation Empleado de Tienda http://jsbsan.blogspot.com.es/2013/12/patron-delegation-ejemplo-empleado-de.html



Comportamiento
Chain of Responsability Ordenes a Rambo http://jsbsan.blogspot.com.es/2013/11/patron-chain-of-responsibility-cadena.html
Command Implementar Deshacer y Rehacer ordenes http://jsbsan.blogspot.com.es/2013/11/patron-command-implementar-deshacer-y.html
Interpreter Evaluador de expresiones http://jsbsan.blogspot.com.es/2013/12/patron-interpreter-ejemplo-evaluador-de.html
Iterator Reccorrer una lista de diversas formas http://jsbsan.blogspot.com.es/2013/12/patron-iterator-ejemplo-recorrer-una.html
Mediator Chat y Conferencia http://jsbsan.blogspot.com.es/2013/11/patron-mediator-ejemplos-chat-y.html
Memento Marcador de futbol http://jsbsan.blogspot.com.es/2013/12/patron-memento-ejemplo-marcador-de.html
Observer Estación Meteorológica http://jsbsan.blogspot.com.es/2013/10/el-patron-observer-estacion.html
State Conexion/Desconexion y Ventanilla del Banco http://jsbsan.blogspot.com.es/2013/12/patron-proxy-ejemplo-realizar-un.html
Strategy Pato: Formas de volar http://jsbsan.blogspot.com.es/2013/10/el-principio-solid-de-open-closed-el.html
Template Method Valoración de un equipo de futbol http://jsbsan.blogspot.com.es/2013/10/patron-de-diseno-template-method.html
Visitor Cliente y Operador: añadiendo métodos http://jsbsan.blogspot.com.es/2013/11/patron-visitor-ejemplo-cliente-y.html

Fuentes:
http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o

jueves, 17 de octubre de 2013

El principio SOLID de Open Closed: El patrón Strategy


 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.
Fuente: wikipedia

¿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.
 - 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.
Para resolver un problema, siempre existen varias formas de hacerlo.¿cual elegir?
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
Ejemplo: Simulador de Patos.
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.blogspot.com.es/2013/01/patrones-de-diseno-en-java-patron.html
 https://github.com/juanitodread/DesignPatterns/tree/master/src/org/juanitodread/designpatterns/strategypattern
Libros:
head_first_design_pattern

Nota: 
Siguiente entrada sobre patrones: Patrón Observer: la estación meteorológica (new)

sábado, 1 de diciembre de 2012

Inteligencia Artifical: Prever el movimiento del contrario


Inteligencia Artificial:
Prever el movimiento del contrario
Juego de Karate


Este es un ejemplo que encontré en el libro IA FOR GAMEDEVOLOPERS, (en la página 301), 


que lo podeis encontrar aqui.


Trata del siguiente problema:
En un juego de lucha, tenemos varios movimientos o golpes (por ejemplo: puñetazo, patada baja, patada alta, etc..) y queremos hacer un algoritmo que "prevea" el movimiento del jugador humano, así nuestra inteligencia artificial, podrá tomar las medidas oportunas, por ejemplo movimientos de defensa (paso atrás) o de contraataque.


La primera forma de hacerlo que se me ocurre,  sería usar probabilidades. Si tuviésemos 3 opciones, las probabilidades que salgan sería de 1/3 (33%)


Pero se puede aplicar un método para que mientras se juegue, el programa aprenda que tipos de "patrones" de movimiento usa el jugador humano y así poder tomar las decisiones oportunas para rechazar el ataque.


El ejemplo se centra en el estudio de las jugadas y predecir cual será el próximo movimiento del jugador humano.


¿como lo hace?

Usando reglas del tipo: If  A y B then C

Se crea una tabla de reglas con las combinaciones de dos movimientos (antecedentes A y B) y el tercero como resultado (consecuente C).

El jugador humano va realizando movimientos, el programa compara lo realizado con las reglas que tiene almacenada, y las que se cumple, las pondera (peso) de manera positiva. De esta manera "aprende" de los patrones de movimientos que hace el jugador humano y cuales son los que usa, según la ponderación o peso de la regla, puede prever el próximo movimiento del jugador humano.


Aqui podeis ver una captura del programa:



Descarga del código fuente en gambas: descarga tar.gz