Patrones de Diseño de Software: Guía Completa

Enviado por Chuletator online y clasificado en Informática y Telecomunicaciones

Escrito el en español con un tamaño de 14,39 KB

Strategy (Policy)

Este patrón de comportamiento define una familia de algoritmos, encapsula cada uno y los hace intercambiables. Permite que el algoritmo varíe de forma independiente a los clientes que lo usan. Para cambiar diferentes implementaciones para diferentes situaciones. Soporta distintas variantes del algoritmo.

Cuándo aplicarlo:

Se necesitan distintas variantes de un algoritmo. Distintos comportamientos de una clase aparecen como varias sentencias condicionales.

Participantes:

  • Strategy: Declara una interfaz común.
  • ConcreteStrategy: Implementa los distintos algoritmos.
  • Context: Se configura con una estrategia concreta.

Ventajas:

  • Se usa para evitar diferentes sentencias condicionales.
  • Permite, en tiempo de ejecución, la selección de algoritmos de la misma familia.
  • Añade extensibilidad para implementaciones de algoritmos de 3º partes.
  • Refuerza el principio Open/Close (Abierta para extensión pero cerrada para modificación).

Desventajas:

Puede incrementar el número de clases ya que cada estrategia necesita ser definida en su propia clase.

Decorator (Wrapper)

Responde a la necesidad de añadir dinámicamente funcionalidad a un objeto. Proporciona una alternativa flexible a la herencia para extender la funcionalidad. La transparencia permite anidar decoradores de forma recursiva ampliando la funcionalidad.

Participantes:

  • Component (Visual com): Define la interfaz de los objetos a los que se les puede añadir responsabilidades dinámicamente.
  • ConcreteComponent
  • Decorator: Mantiene una referencia a un objeto Component y tiene su misma interfaz.
  • ConcreteDecorator: Añade responsabilidades al componente.

Ventajas:

  • Más flexible que la herencia estática.
  • Evita que las clases de arriba de la jerarquía estén repletas de funcionalidades.

Desventajas:

  • Un decorador y sus componentes no son idénticos.
  • Muchos objetos pequeños.

Adapter

Este patrón estructural convierte la interfaz de una clase en otra interfaz que el cliente espera. Es posible utilizarlo para usar una clase existente y ésta no tiene la interfaz que necesitamos, queremos crear una clase reutilizable que coopere con clases con las que no está relacionada o (OO) usar varias subclases existentes, pero sin tener que adaptar su interfaz creando una subclase de cada una.

Cuándo aplicarlo:

  • Queremos usar una clase existente y esta no tiene la interfaz que necesitamos.
  • Queremos crear una clase reutilizable que coopere con las que no está relacionada.

Participantes:

  • Target: Define la interfaz específica del dominio.
  • Cliente: Colabora con los objetos de tipo Target.
  • Adaptee: La clase existente cuya interfaz necesita ser adaptada.
  • Adapter: Adapta la interfaz de Adaptee a la de Target.

Ventajas:

  • La clase adaptador puede sobrescribir el comportamiento del Adaptee.
  • Mejora la reusabilidad y la flexibilidad.

Composite

Este patrón estructural permite componer objetos en estructuras arbóreas para representar jerarquías de todo-parte, de modo que los clientes puedan tratar a los objetos individuales y a los compuestos de manera uniforme.

Cuándo aplicarlo:

  • Representar jerarquías de parte-todo.
  • Que los clientes traten por igual los objetos individuales y compuestos.

Participantes:

  • Component: Declara la interfaz común. Implementa el comportamiento predeterminado común a todas las clases. Declara operaciones para acceder a los hijos.
  • Leaf
  • Composite: Almacena sus componentes hijos. Implementa las operaciones relacionadas con los hijos.
  • Client: Manipula los objetos de la composición a través de la interfaz Component.

Ventajas:

  • Permite jerarquías de objetos tan complejas como se quiera.
  • Simplifica el cliente.
  • Se pueden añadir nuevos componentes fácilmente.

Desventajas:

Podría hacer el diseño demasiado general.

Command (Action/Transaction)

Este patrón de comportamiento encapsula una petición dentro de un objeto, permitiendo parametrizar a los clientes con distintas peticiones, encolarlas, guardarlas en un registro de sucesos o implementar un mecanismo de deshacer/repetir. Lo que permite Command es desacoplar al objeto que invoca a la operación de aquel que tiene el conocimiento necesario para realizarla.

Cuándo aplicarlo:

  • Cuando se quiera parametrizar objetos con una determinada acción.
  • Que la acción a realizar y el objeto tengan ciclos de vida distintos.
  • Permitir undo/redo.
  • Guardar las operaciones ejecutadas en un log.
  • Usar transacciones.

Participantes:

  • Command: Define una interfaz para ejecutar una operación.
  • ConcreteCommand: Asocia un objeto Receiver con una acción. Implementa execute.
  • Client: Crea un objeto ConcreteCommand y establece su receptor.
  • Invoker: Ejecuta la acción.
  • Receiver.

Ventajas:

  • Desacoplar el objeto que llama a la operación del que sabe cómo llevarla a cabo.
  • Son objetos. Se pueden ensamblar.
  • Resulta sencillo añadir nuevas acciones.

State

Este patrón de comportamiento permite a un objeto alterar su comportamiento cuando cambia su estado interno. Parecerá como si el objeto hubiera cambiado su clase.

Cuándo aplicarlo:

  • El comportamiento de un objeto depende de su estado.
  • Las operaciones tienen sentencias condicionales anidadas que tratan con los estados.

Participantes:

  • Context: Define la interfaz que interesa a los clientes y mantiene una referencia a una subclase de estado concreto que representa el estado actual.
  • State: Define la interfaz para encapsular el comportamiento asociado con el estado del contexto.
  • Subclases ConcreteState: Cada subclase implementa las operaciones para ese estado concreto.

Ventajas:

  • Localiza el comportamiento específico del estado y lo aísla en un objeto.
  • Se pueden añadir nuevos estados y transiciones fácilmente definiendo subclases de State.
  • Hace explícitas las transacciones entre estados.

Template

Este patrón de comportamiento de clases define el esqueleto de un algoritmo en una operación, difiriendo algunos pasos hasta las subclases. Permite que éstas redefinan ciertos pasos del algoritmo sin cambiar la estructura del mismo.

Cuándo aplicarlo:

  • Para implementar las partes de un algoritmo que no cambian y dejar que las subclases implementen aquellas otras que pueden variar.
  • Como motivo de factorizar código, cuando movemos cierto código a una clase base común para evitar duplicidad.
  • Para controlar el modo en que las subclases extienden la clase base.

Participantes:

  • AbstractClass App: Define las operaciones primitivas abstractas que redefinirán las subclases. Implementa un método de plantilla con el esqueleto del algoritmo.
  • AbstractClass MyApp: Implementa las operaciones primitivas.

Ventajas:

  • Los templates son una técnica fundamental para la reutilización de código.
  • Inversión de control.

Observer (Publish-Sub)

Este patrón de comportamiento de objetos define una dependencia uno-a-muchos entre objetos, de modo que cuando un objeto cambia su estado, todos los demás objetos dependientes se modifican y actualizan automáticamente.

Cuándo aplicarlo:

  • Una abstracción tiene dos aspectos, uno de los cuales depende del otro.
  • Un cambio en un objeto requiere que cambien otros.
  • Un objeto necesita notificar a otros cambios en su estado sin hacer presunciones sobre quiénes son dichos objetos.

Participantes:

  • Subject: Conoce a sus observadores. Proporciona una interfaz para que se suscriban los objetos Observer.
  • Observer: Define una interfaz para actualizar los objetos que deben ser notificados de cambios en el objeto Subject.
  • ConcreteSubject: Guarda el estado de interés para los objetos ConcreteObserver. Envía una notificación a sus observadores cuando cambia su estado.
  • ConcreteObserver: Mantiene una referencia a un objeto ConcreteSubject. Guarda el estado que debería permanecer sincronizado con el objeto observado. Implementa la interfaz Observer para mantener su estado consistente con el objeto observado.

Ventajas:

  • Permite variar objetos observados y observadores independientemente.
  • Acoplamiento abstracto entre Subject y Observer.
  • No se especifica el receptor de una actualización (se envía a todos los interesados).

Desventajas:

Actualizaciones inesperadas (en cascada ineficientes).

¿Quién llama a notify?

El objeto observado cada vez que cambia su estado o los clientes.

Visitor

Este patrón de comportamiento de ámbito de objetos representa una operación a realizar sobre una estructura de objetos. Permite definir nuevas operaciones sin modificar las clases de los elementos sobre los que opera.

Cuándo aplicarlo:

  • Una estructura de objetos contiene muchas clases de objetos con diferentes interfaces y queremos realizar operaciones sobre esos elementos que depende de su clase.
  • Se necesitan realizar muchas operaciones distintas y no relacionadas sobre objetos de una estructura de objetos y queremos evitar añadir demasiadas operaciones.
  • Cuando queremos definir nuevas operaciones sobre la estructura de objetos sin redefinir la interfaz para todos los visitantes.

Participantes:

  • Visitor: Declara la operación visit para cada clase de operación ConcreteElement de la estructura de objetos e identifica a la clase que envía la petición.
  • ConcreteVisitor: Implementa cada operación declarada por Visitor.
  • Element: Define una operación accept que recibe un visitante como argumento.
  • ConcreteElement: Implementa "accept".
  • ObjectStructure: Puede enumerar sus elementos, proporcionar una interfaz de alto nivel y puede ser un compuesto o una colección.

Ventajas:

  • El visitante facilita añadir nuevas operaciones.
  • Un visitante agrupa operaciones relacionadas y separa las que no lo están.

Desventajas:

Es difícil añadir nuevas clases de elementos concretos.

Prototype

Este patrón especifica los tipos de objetos a crear usando una instancia prototípica y crea nuevos objetos copiando dicho prototipo.

Cuándo aplicarlo:

Cuando un sistema no pueda o no deba conocer cómo se crean, componen y representan los productos, y además las clases a instanciar son definidas en tiempo de ejecución; para evitar construir una jerarquía paralela de factorías de productos o cuando las instancias de una clase puedan tener solo unos pocos posibles estados.

Participantes:

  • Prototype: Declara la interfaz para clonarse.
  • ConcretePrototype: Implementa la operación de clonación.
  • Client: Crea un nuevo objeto diciéndole al prototipo que se clone.

Ventajas:

  • Permite añadir y eliminar productos dinámicamente.
  • Especifica nuevos objetos modificando valores de sus propiedades.
  • Reduce las subclases.

Desventajas:

La implementación de la operación de clonación puede no ser fácil.

Abstract Factory

Define una interfaz para crear familias de objetos relacionados sin especificar sus clases concretas.

Cuándo aplicarlo:

Si queremos que una aplicación se aproveche de ello y sea portable, no podrá crear directamente objetos de esas clases específicas.

Ventajas:

  • Aísla las clases concretas - Los clientes manipulan los productos únicamente a través de sus interfaces abstractas.
  • Permite intercambiar fácilmente familias de productos - Basta con cambiar una única clase, en un único sitio: la fábrica concreta.

Desventajas:

  • Promueve la consistencia entre los productos.
  • Dificulta añadir nuevos tipos de productos.

Factory Method

Define una interfaz para crear un objeto, pero deja que sean las subclases quienes decidan la clase del objeto a crear.

Cuándo aplicarlo:

  • Una clase no puede anticipar la clase de objetos que debe crear.
  • Una clase quiere que sus subclases especifiquen los objetos a crear.
  • Hay clases que delegan responsabilidades en una o varias subclases, y queremos localizar el conocimiento de qué subclase es el delegado.

Participantes:

  • Product: Define la interfaz de los objetos creados por el método de fabricación.
  • ConcreteProduct: Implementa la interfaz Product.
  • Creator: Declara el método de fabricación.
  • ConcreteCreator: Redefine el método de fabricación para devolver un objeto ConcreteProduct.

Ventajas:

  • Elimina la necesidad de enlazar clases específicas de la aplicación en el código - Sólo maneja la interfaz Product.

Desventajas:

Tener que crear una subclase de Creator en los casos en los que ésta no fuera necesaria de no aplicar el patrón.

Entradas relacionadas: