Patrones de Diseño Software de Comportamiento

Introducción

Los patrones de diseño software de comportamiento son aquellos que están relacionados con algoritmos y con la asignación de responsabilidades a los objetos.
Describen no solamente patrones de objetos o de clases, sino que también engloban patrones de comunicación entre ellos. Al igual que los otros tipos de patrones, se pueden clasificar en función de que trabajen con clases (Template Method, Interpreter) u objetos (Chain of Responsability, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Visitor).

La variación de la encapsulación es la base de muchos patrones de comportamiento. Cuando un aspecto de un programa cambia frecuentemente, estos patrones trabajan con un objeto que encapsula dicho aspecto, teniendo que definir por tanto, una clase abstracta que describe la encapsulación del objeto.

A continuación, definiremos algunos de los patrones de diseño software comportamiento más habituales.


Command

El patrón de diseño software de comportamiento Command permite realizar una operación sobre un objeto sin conocer realmente las instrucciones de esta operación ni el receptor real de la misma. Esto se consigue encapsulando la petición como si fuera un objeto, con lo que además se facilita la parametrización de los métodos.

Las principales aplicaciones del patrón de comportamiento Command serían:

  • - Facilitar la parametrización de las acciones a realizar.
  • - Implementar estructuraas de CallBack, especificando qué órdenes queremos que se ejecuten efrente a qué situaciones.
  • - Independizar los enventos de "petición" y "ejecución".
  • - Dar un soporte factible a la operación "deshacer".
  • - Desarrollar sistemas utilizando órdenes de alto nivel que se construyen con primitivas.

Los principales agentes de este patrón son:

  • Command: Declara la interface para la ejecucion de la operacion.
  • ConcreteCommand: Define la relación entre el objeto Receiver y una acción, además de implemetar el método básico Execute() al invocar las operaciones correspondientes en Receiver.
  • Client: Crea un objeto ConcreteCommand y lo relaciona con su Receiver.
  • Invoker: Envía las solicitudes al objeto Command.
  • Receiver: Es la clase que gestiona la ejecución de las operaciones asociadas a la solicitud. Cualquier clase puede ser receptora.

Este sería el diagrama de clases general del patrón de comportamiento Command:

Esquema Command
Esquema del patrón Command

En este enlace podrá consultar un código de ejemplo en Java del patrón de comportamiento Command.


Iterator

El patrón de diseño de comportamiento Iterator es uno de los mayores exponentes de los patrones de comportamient. Presenta la interfaz que declara los métodos necesarios para acceder, de forma secuencial, a los objetos de una colección.
El iterator cubre la necesidad de acceder a los elementos de un contenedor de objetos sin tener que trabajar con su estructura interna. Además, es posible que se necesite más de una forma de recorrer la estructura siendo para ello necesario crear modificaciones en la clase. Mediante el uso del patrón, se añaden métodos que permiten recorrerla sin referenciar su representación, por lo que la responsabilidad del recorrido se traslada a un objeto iterador.
La gran desventaja de que usar este objeto iterador, más o menos encapsulado, es que muchas veces e necista conocer la estructura del contenedor para elegir del tipo de iterador más adecuado. Esto se soluciona abstrayendo los tipos de los distintos iteradores y dotando a las estructuras de un método que cree un iterador concreto.

Las entidades participantes en el esquema general de este patrón de diseño software de comportamiento son:

  • Iterator: Interfaz que se usará para recorrer el contenedor y acceder a los objetos o elementos que albergue, de tal modo que no sea necesario conocer los detalles de la estructura, siendo capaces de manejarla de todos modos.
  • ConcreteIterator: Clase que implementa la interfaz propuesta por el Iterator. Mantendrá la posición actual en el recorrido de la estructura almacenándola en el aggregate, sabiendo así cual será el siguiente objeto en el recorrido.
  • Aggregate: Es la interfaz que se usará para la fabricación de iteradores.
  • ConcreteAggregate: Implementa la estructura de datos y el método de fabricación de iteradores que crea un iterador específico para su estructura.

Por lo tanto, es fundamental que se implemente el control de la iteración y definir el recorrido, bien sea como un iterador externo o como uno interno que presente una actuación concreta sobre la estructura aplicándola, de forma transparente, a todos los elementos.

Este sería el diagrama de clases general de este patrón de comportamiento:

Esquema Iterator
Esquema del patrón Iterator

En este enlace podrá consultar un código de ejemplo en Java del patrón de comportamiento Iterator.


Observer

El patrón de comportamiento Observer define una interacción entre objetos, de manera que cuando uno de ellos cambia su estado, el Observer se encarga de notificar este cambio a los demás.
Por tanto, la razón de ser de este patrón es desacoplar las clases de los objetos, aumentando la modularidad del lenguaje y evitando bucles de actualización.
La idea básica del patrón es que el objeto de datos (o sujeto) contenga atributos mediante los cuales cualquier objeto observador (o vista) se pueda suscribir a él pasándole una referencia a sí mismo. De este modo, el sujeto mantiene así una lista de las referencias a sus observadores.

Dadas estas propiedades, el patrón Observer suele emplearse en el desarrollo de frameworks de interfaces gráficas orientados a objetos, enlazando 'listeners' a los objetos que pueden disparar eventos.

Las clasese participantes en el esquema general de este patrón de comportamiento son:

  • Subject: Es el que conoce a sus observadores, proporcionando una Interfaz para que se suscriban los objetos de tipo Observer.
  • Observer: Define la interfaz para actualizar los objetos a los que se deben notificar los cambios en el objeto Subject.
  • ConcreteSubject: Guarda el estado de interés para los objetos ConcreteObserver y envia una notificación a sus observadores cuando cambia su estado.
  • ConcreteObserver: Mantiene una referencia a un objeto ConcreteSubject, guardando el estado que debería permanecer sincronizado con el objeto observado, además de implementar la interfaz Observer para mantener su estado consistente con el objeto observado.

Este sería el diagrama de clases general del patrón de comportamiento Observer:

Esquema Observer
Esquema del patrón Observer

En este enlace podrá consultar un código de ejemplo en Java del patrón de comportamiento Observer.


Strategy

Este es un patrón de diseño software de comportamiento que determina la forma de implementar el intercambio de mensajes entre diferentes objetos que realizan diferentes tareas, pero que comparten elementos comunes. El patrón de comportamiento Strategy permite gestionar un conjunto de operaciones de entre los cuales el cliente puede elegir el que le convenda más en cada situación, e intercambiarlo, de forma dinámica, cuando lo necesite.

Para llevar a cabo esta funcionalidad, este patrón de comportamiento trabaja con los algoritmos que implementan las diferentes estrategias de forma que los encapsula en una jerarquía, consiguiendo que el cliente trabaje contra un objeto intermediario o 'Context'. En este punto, el cliente puede elegir el algoritmo que prefiera de entre los implementados en las estrategias del sistema, o dejar al contexto la tarea de elejir al más apropiado para cada situación concreta.
Por lo tanto, cualquier sistema que presente un servicio o función determinada, que pueda o deba ser realizada de varias maneras dependiendo del contexto, será indicado gestionarlo con el patrón Strategy.

Las clasese participantes en el esquema general de este patrón de comportamiento son:

  • Context: Actor que necesita de las operaciones concretas de las diferentes estrategias, referenciando a estas últimas. Puede definir una interfaz intermedia que facilite el acceso a sus datos propios por parte de la estrategia necesaria, en caso de necesitar el intercambio de información entre el Context y diche estrategia.
  • Strategy: Es la interfaz común para todos los algoritmos implementados en las diferentes estrategias. Será lo que use el Context para invocar a la estrategia concreta que necesite.
  • ConcreteStrategy: Clases donde se implementan los algoritmos necesarios, usando para ello la interfaz Strategy.

Este sería el diagrama de clases general del patrón de comportamiento Strategy:

Esquema Strategy
Esquema del patrón Strategy

En este enlace podrá consultar un código de ejemplo en Java del patrón de comportamiento Strategy.