Patrones de Diseño Software Estructurales

Introducción

Los patrones de diseño estructurales están enfocados en la gestión de la forma en la que las clases y los objetos se combinan para dar lugar a estructuras más complejas. Al igual que en las otros tipos de patrones, podemos hablar de patrones estructurales asociados a clases (Adapter) y asociados a objetos (Bridge, Composite, Decorator, Facade, Flyweight, Proxy). Los primeros utilizan la herencia mientras que los segundos se basan en la composición. Los patrones estructurales asociados a objetos describen formas de componer los objetos para conseguir nuevas funcionalidades. La flexibilidad de la composición de estos objetos surge de la posibilidad de cambiar dicha composición en tiempo de ejecución, lo que es imposible con la composición estática tradicional de clases.


Adapter

El patrón Adapter convierte la interfaz de una clase en la que otra necesita, permitiendo que clases con interfaces incompatibles trabajen juntas.

Por lo tanto, el uso de este patrón estructural está indicado cuando se quiere usar una clase ya implementada y su interfaz no es similar con la necesitada o cuando se desea crear una clase reusable que coopere con clases no relacionadas o que tengan interfaces compatibles.

Sin embargo, hay que hacer distinción entre si queremos adaptar un objeto o una clase o interfaz completa.
Un adaptador de clase adapta la clase Adaptee a la interfaz de la clase Target, trabajando con una clase adaptada concreta. Por ello, una clase adaptadora no funcionará cuando se desee adaptar, además de la clase objetivo, todas sus subclases.
Sin embargo, un adaptador de objetos permite que un único Adapter trabaje con muchos Adaptees. De este modo, el Adapter también puede agregar funcionalidad a todos los Adaptees de una sola vez.

Los participantes de este patrón serían los siguientes:

  • Client: Es el principal agente en la formación de objetos para la interfaz Target.
  • Target: Interfaz del dominio específico que usa el Client.
  • Adaptee: Es la interfaz ya existente que necesita adaptarse.
  • Adapter: Es quien adapta la interfaz del Adaptee a la interfaz Target.

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

Esquema Adapter
Esquema del patrón Adapter

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



Composite

El patrón Composite sirve para construir objetos que estén formados por tros objetos más simples, pero siempre similares entre sí, gracias a la composición recursiva. Por lo tanto, al tner todos estos objetos una misma interfaz, el Composite simplifica el tratamiento de los mismos.

El patrón composite es ampliamente usado en el tratamiento de interfaces de usuario en las que se necesita, por ejemplo, representar un conjunto de elementos de una interfaz gráfica. Algunos de estos elementos serán simples, mientras que otros serán más complejos y estarán formados por varios elementos simples. Por tanto, el comportamiento y/o la información que proporciona un elemento complejo está determinada por los elementos que lo componen.
Generalizando, nos encontraríamos frente a una situación en la que neceistaríamos representar jerarquías de objetos de tipo parte y compuestos en la que se quiere usar la misma interfaz en las partes y en los compuestos. El patrón Composite, lo que nos ofrece es crear una interfaz o clase abstracta que actúe comosuperclase de las clases concretas que representan las partes y los compuestos. Las clases que representan los compuestos pueden ser tratadas como partes, porque soportan la interfaz.

De este modo, encontramos que los componentes del patrón serían los siguientes:

  • Client: Manipula objetos atravez de la interfaz proporcionada por Component.
  • Component: Declara la interfaz para los objetos de la composicion, es la interfaz de acceso y manipulacion de los componentes hijo e implementa algunos comportamientos por defecto.
  • Composite: Define el comportamiento de los componentes compuestos, almacena a los hijos e implementa las operaciones de manejo de los componentes.
  • Leaf: Definen comportamientos para objetos primitivos del compuesto.

Según esto, este sería el diagrama de clases general del patrón:

Esquema Composite
Esquema del patrón Composite

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



Decorator

El patrón de diseño estructural Decorator facilita la tarea de añadir dinámicamente funcionalidades a un Objeto. De este modo, elimina de necesidad de crear clases que fuesen heredando de la primera, incorporando no sólo la nueva funcionalidad, sino también otras nuevas y asociarlas a ella.

A veces se desea adicionar responsabilidades a un objeto pero no a toda la clase. Las responsabilidades se pueden adicionar por medio de los mecanismos de Herencia, pero este mecanismo no es flexible porque la responsabilidad es adicionada estáticamente. La solución flexible es la de rodear el objeto con otro objeto que es el que adiciona la nueva responsabilidad. Este nuevo objeto es el Decorator.

Este ejemplo de patrones estructurales de diseño software es útil cuando:

  • - Queremos añadir o expander las funcionalidades de objetos de forma dinámica y transparente.
  • - Necesitamos que ciertas responsabilidades de un objeto puedan ser retiradas de forma sencilla en un futuro.
  • - No es posible o no compensa realizar esta expansión de funcionalidades mediante herencia.
  • - Existe la necesidad de expandir dinámicamente la funcionalidad de un objeto y/o eliminar la funcionalidad extendida.

Visto esto, señalar que los participantes de este patrón serían los siguientes:

  • Component: Define la interface de los objetos a los que se le puede adicionar responsabilidades dinamicamente.
  • ConcreteComponent: Define el objeto al que se le puede adicionar una responsabilidad.
  • Decorator: Mantiene una refeencia al objeto Component y define una interface de acuerdo con la interface de Component.
  • ConcreteDecorator: Es el encargado de sumar la responsabilidad al componente. Puede haber varipos ConcreteDecorator.

Por lo tanto, este sería el diagrama de clases general del patrón:

Esquema Decorator
Esquema del patrón Decorator

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



Proxy

Esta patrón estructural tiene como propósito proporcionar un intermediario para controlar el acceso a un objeto. Por ello tiene distintas aplicaciones:

  • - Proxy Remoto: Denominado así cuando representa a un objeto remoto.
  • - Proxy Virtual: Usado para crear objetos bajo demanda.
  • - Proxy de Referencia "inteligente": Cuando sirve como sustituto de un puntero que realiza operaciones adicionales cuando accede al objeto.
  • - Proxy de Protección: Denominado así cuando se usa para controlar el acceso al objeto original.

La finalidad principal del patrón de diseño estructural Proxy, sería proporciona un representante o sustituto de otro objeto para controlar el acceso a éste. Esto lo hace según la motivación deMotivación: retrasar el coste de crear e inicializar un objeto hasta que sea realmente necesario. Por lo tanto, es usado cuando se necesita una referencia a un objeto más flexible o sofisticado que un puntero. Por ejemplo, si que queremos construir una aplicación que usa muchos objetos visuales, lo ideal es que dichos objetos sólo se instanciaran cuando se vayan a utilizar, de tal forma que se ahorre carga en memoria y tiempo.

Con esto, las clases participantes en el patrón, serían las siguientes:

  • Proxy: Mantiene una referencia al objeto real, mientras que proporciona una interfz idéntica a la del objeto real (Real Subject) y controla el acceso a este objeto, siendo responsable de crearlo y borrarlo.
  • Subject: Define una interfaz común para el proxy y el objeto real.
  • RealSubject: Clase del objeto real que el proxy representa.

Según esto, este sería el diagrama de clases general del patrón:

Esquema Proxy
Esquema del patrón Proxy

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