Patrones de diseño

Patrones de diseño. Introducción

¿Qué es un patrón de software?

En software un patrón de diseño se refiere a una determinada forma de crear software, una forma de fabricarlo, por decirlo de alguna forma para crearlo de forma correcta.

En determinados marcos de trabajo, cuando nos enfrentamos a determinados problemas en el diseño de software hay formas determinadas de enfocalos que permiten adaptar mejor los posibles cambios de dichos problemas y las distintas evoluciones que pueda sufrir el software en un futuro.

Un buen dominio de los patrones más comunes nos puede servir para no tener que reinventar la rueda a cada paso que damos sino que podemos hacer uso de lo que otros pensaron por nosotros (y que descubriremos en multiples situaciones).

Patrones de diseño. Strategy

Introducción

El patrón strategy (estrategia) esta orientado a resolver situaciones en las que nos encontramos con un problema base pero existen diversas estrategias para abordar el problema. En este sentido nuestro problema define un interface que será (o podrá ser) implementado de diversas formas.

Problema

El patrón Strategy aborda problemas que pueden (o se prevee que puedan) ser implementados o afrontados de distintas formas y cuyo interfaz esta bien definido y es común para dichas formas, pudiendo ser cualquiera de ellas valida o más desable en determinadas situaciones y permitiendo el cambio entre las distintas estrategias en tiempo de ejecución.

Estructura

main.php?g2_view=core.DownloadItem&g2_itemId=825&g2_serialNumber=1

Patrones de diseño. Template Method

Introducción

El patrón de diseño Template Method se utiliza en situaciones en las cuales existe un determinado esqueleto que conforma pasos comunes dentro de un algoritmo o procedimiento en una clase.

Una analogía podría ser la forma en que resolvemos un problema con distintos expertos, por ejemplo, supongamos el caso del ciclo de vida del software (simplificado), que podemos estructurar en los siguientes pasos:

  • Preparar un documento de concepto
  • Elaborar la especificación de requisitos
  • Elaborar el diseño de la aplicación
  • Codificar la solución
  • Realizar las pruebas unitarias
  • Realizar las pruebas de sistema

Ahora bien, el proceso es el mismo cada vez. El documento de concepto puede realizarlo comercial o marqueting, elaborarlo en Word o en PDF. El formato del documento de requisitos puede cambiar o usar un programa de apoyo como DOORS y el código puede realizarse utilizando Delphi, C# o Java, pero el proceso general permanece el mismo, solo cambian los expertos que se encargan de cada cosa.

Patrones de diseño. Memento Pattern.

Introducción

En muchas ocasiones deseamos guardar el estado de un objeto de forma que podamos recuperar dicho estado en cualquier momento. Un ejemplo muy simple es que vayamos a modificar una serie de parametros del objeto y hacer alguna operación pero deseemos almacenar en que estado estaba ese objeto para poder volver a él en caso de que se produzca una excepción.

En la mayoría de los objetos existe una parte de su estado que queda recogida en variables privadas. Al contrario de lo que se suela pensar una campo es privado no para evitar que alguien pueda modificarlo (que tangencialmente también) sino para indicar al programador que usa la clase que dicho campo no le interesa y no debe tenerlo en cuenta, utilizarlo ni depender en ningún sentido. Si cambiamos dichas variables de privadas a publicas, conseguimos que quien quiere guardar el estado pueda hacerlo leyendo y almacenando los campos pero violamos el concepto anterior.

El patrón memento enfrenta este problema encapsulando la información interna del objeto en una objeto, preferiblemente opaco al exterior.

Patrones de diseño. Facade Pattern

Introducción

El patrón Façade es un patrón de software cuyo objetivo se basa en simplificar o hacer más amigable la complejidad asociada a una librería software.

En ocasiones una librería o serie de librerias contienen una serie de funcionalidades para realizar diversas acciones. Si se analiza, en la gran mayoría de los proyectos de software, se observará que la mayor parte de las llamadas que recibe la librería es a las mismas funciones o a una combinación de ellas. Es decir, existe una gran cantidad de peticiones comunes que suelen ocurrir en el 90% de los casos y que satisfacen las necesidades del cliente de la librería. En estos casos, es convieniente crear un objeto que simplifica el API de la librería, unificando y simplicando ciertos procesos del API. Por supuesto algunos programas todavía querran (y podrán) acceder al viejo API de la librería para utilizar algunas funciones especializadas pero se habrá conseguido simplificar la funcionalidad más comunmente usada de la librería.

Patrones de diseño. Command Pattern

Introducción

El patrón Command (command pattern) es un patrón de diseño en el que los objetos representan acciones que serán consumidas por algún consumidor.

Problema

El patrón Command se utiliza para resolver diversos tipos de problemas en desarrollo de software:

  • Usado como simplificación de llamadas. En ocasiones el número de parámetros de una función crece hasta hacerse inmanejable. El uso del patrón command permite agrupar los parámetros en un solo objeto que se pasará a la función.
  • Usado como cola de comandos. Encapsular cada comando en un objeto permite su procesamiento de forma secuencial en forma de cola, de forma que un proceso trabajador pueda ir sacando los trabajos de dicha cola.
  • Operaciones con histórico. Usando objetos como comando y manteniendo esos comandos podemos mantener un histórico de los comandos utilizados y, en caso necesario, revertirlos.
  • Generalización de comandos. En ocasiones el uso de comandos permite la abstracción de dicho comando de forma que el comando constituye una clase abstracta de la que heredan los comandos específicos y que permite que un determinado objeto procese comandos ajustados a un determinado esquema independientemente de lo que haga dicho parámetro.

Patrones de diseño. Abstract Factory Pattern

Introducción

La idea detrás del patron Abstract Factory (que en español se traduciría como fabrica abstracta) consiste en la noción de que nuestro programa (o el cliente de una clase que nosotros proporcionamos) trabaja con una serie de productos (como los de una fábrica) que tienen unas determinadas características (por ejemplo tenemos productos embotellados y productos en tetrabrick). Nuestro programa va a utilizar dichos productos realizando una serie de acciones sobre ellos (como meter las botellas en unos camiones y los tetrabricks en otros) sin importarle quien le está suministrando los productos.

Así mismo existen una serie de fábricas que producen esos productos que vamos a tratar, una fábrica fabrica cocacola y otra pepsi pero ambas en botellas de las que nuestro programa trata. Al final, el concepto básico consiste en que a nuestro programa (o cliente) no le importa lo que haya dentro de la botella ni quien lo haya producido mientras sea una botella.

El punto de vista software

Desde el punto de vista software el ejemplo anterior se traduce en una situación en la que nuestro programa maneja un tipo de objetos con unas características comunes y algunas caracterísiticas propias. Esto en general en software se resuelve mediante el uso de dos características de los lenguajes de programación orientados a objetos, las clases+abstractas+y+los+interfaces.

Patrones de diseño. Adapter Pattern

Introducción

El patrón Adapter (o adaptador), también conocido a veces como wrapper realiza la función, como su nombre indica de adaptar (o envolver) una determinada clase cambiando el interfaz de dicha clase y convirtiendolo en algo que se acerque más a nuestras necesidades.

En muchas ocasiones tenemos una clase que hace lo que necesitamos (o se aproxima mucho) y cumple todos los requisitos para que alguna otra clase la use pero, al no implementar un determinado interface o derivar de una determinada clase esto no es posible.

Problema

En un determinado punto del código se espera una instancia de un determinado interfaz o de una determinada clase. Deseamos utilizar una clase distinta que cumple todos los requisitos del interfaz o de la clase concreta que se espera en el código pero que, sin embargo, por las razones que sean no implementa dicho interfaz.