🎃 Grandes descuentos en libros en línea, eformaciones y vídeos*. Código CALABAZA30. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Patrones de diseño en C#
  3. El patrón State
Extrait - Patrones de diseño en C# Los 23 modelos de diseño: descripción y soluciones ilustradas en UML 2 y C# [2ªedición]
Extractos del libro
Patrones de diseño en C# Los 23 modelos de diseño: descripción y soluciones ilustradas en UML 2 y C# [2ªedición] Volver a la página de compra del libro

El patrón State

Descripción

El patrón State permite a un objeto adaptar su comportamiento en función de su estado interno.

Ejemplo

Nos interesamos a continuación en los pedidos de productos en nuestro sitio de venta online. Están descritos mediante la clase Pedido. Las instancias de esta clase poseen un ciclo de vida que se ilustra en el diagrama de estados y transiciones de la figura 4-9.1. El estado EnCurso se corresponde con el estado en el que el pedido está en curso de creación: el cliente agrega los productos. El estado Validado es el estado en el que el pedido ha sido validado y aprobado por el cliente. Por último, el estado Entregado es el estado en el que los productos han sido entregados.

images/fig251.PNG

Figura 4-9.1 - Diagrama de estados y transiciones de un pedido

La clase Pedido posee métodos cuyo comportamiento varía en función de este estado. Por ejemplo, el método agregaProducto sólo permite agregar productos si el pedido se encuentra en el estado EnCurso. El método borra no tiene ninguna acción en el estado Entregado.

El enfoque tradicional para resolver estas diferencias en el comportamiento consiste en utilizar condiciones en el cuerpo de los métodos. Este enfoque conduce a menudo a métodos complejos de escribir y de comprender.

El patrón State proporciona otra solución que consiste en transformar cada estado en una clase. Esta clase incluye los métodos de la clase Pedido dependiendo de los estados confiriendo el comportamiento propio de cada estado.

La figura 4-9.2 ilustra...

Estructura

1. Diagrama de clases

La figura 4-9.3 ilustra la estructura genérica del patrón.

images/figure25-3.png

Figura 4-9.3 - Estructura del patrón State

2. Participantes

Los participantes del patrón son los siguientes:

  • MáquinaEstados (Pedido) es una clase concreta que describe los objetos que son máquinas de estados, es decir que poseen un conjunto de estados que pueden ser descritos mediante un diagrama de estados y transiciones. Esta clase mantiene una referencia hacia una instancia de una subclase de Estado que define el estado en curso.

  • Estado (EstadoPedido) es una clase abstracta que incluye los métodos ligados al estado y que gestionan la asociación con la máquina de estados.

  • EstadoConcretoA y EstadoConcretoB (PedidoEnCurso, PedidoValidado y PedidoEntregado) son subclases concretas que implementan el comportamiento de los métodos relativos a cada estado.

3. Colaboraciones

La máquina de estados delega las llamadas a los métodos dependiendo del estado en curso hacia un objeto de estado.

La máquina de estados puede transmitir al objeto de estado una referencia hacia sí misma si es necesario. Esta referencia puede pasarse durante la delegación o en la propia inicialización del objeto de estado.

Dominios de aplicación

El patrón se utiliza en los siguientes casos:

  • el comportamiento de un objeto depende de su estado;

  • la implementación de esta dependencia del estado mediante instrucciones condicionales se vuelve muy compleja.

Ejemplo en C#

A continuación presentamos el ejemplo de la figura 4-9.2 escrito en C#. La clase Pedido se describe a continuación. Los métodos agregaProducto, suprimeProducto y borra dependen del estado. Por consiguiente su implementación consiste en llamar al método correspondiente de la instancia referenciada mediante estadoPedido.

El constructor de la clase inicializa el atributo estadoPedido con una instancia de la clase PedidoEnCurso. El método estadoSiguiente pasa al estado siguiente asociando una nueva instancia al atributo estadoPedido.

using System; 
using System.Collections.Generic; 
 
public class Pedido 
{ 
    protected IList<Producto> productos = new List<Producto>(); 
    public IList<Producto> Productos 
    { 
        get 
        { 
            return productos; 
        } 
    } 
    protected EstadoPedido estadoPedido; 
 
    public Pedido() 
    { 
        estadoPedido = new PedidoEnCurso(this); 
    } 
 
    public void agregaProducto(Producto producto) 
    { 
        estadoPedido.agregaProducto(producto); 
    } 
 
    public void suprimeProducto(Producto producto) 
    { 
        estadoPedido.suprimeProducto(producto); 
    } 
 
    public void...