[Design Pattern Series 19] Análisis del principio del modo de estado y su diferencia del modo de estrategia y el modo de cadena de responsabilidad

Descripción general de la serie de patrones de diseño

Patrones de diseño Boleto aereo
Tres modelos de fábrica Entrada de embarque
Modo de estrategia Entrada de embarque
Modo de delegación Entrada de embarque
Patrón de método de plantilla Entrada de embarque
Modo observador Entrada de embarque
Modo singleton Entrada de embarque
Modo de prototipo Entrada de embarque
Modelo de agencia Entrada de embarque
Modo decorador Entrada de embarque
Modo adaptador Entrada de embarque
Modo constructor Entrada de embarque
Modelo de cadena de responsabilidad Entrada de embarque
Modelo de peso mosca Entrada de embarque
Modo de combinación Entrada de embarque
Patrón de fachada Entrada de embarque
Modo Puente Entrada de embarque
Modelo intermediario Entrada de embarque
Modo iterador Entrada de embarque
Modo de estado Entrada de embarque
Modo intérprete Entrada de embarque
Modo de nota Entrada de embarque
Modo de comando Entrada de embarque
Modo visitante Entrada de embarque
Resumen de 7 principios y patrones de diseño de diseño de software Entrada de embarque

Prefacio

El estado es bastante familiar para nosotros los desarrolladores. En el desarrollo normal, el estado del objeto es siempre inseparable. Por ejemplo, nuestro proceso de revisión es un proceso de flujo de estado continuo, y el proceso de pedido es también un proceso de flujo de estado continuo y modo de estado Es para resolver mejor la lógica de procesamiento comercial en nuestro proceso de circulación estatal.

Que es el modo de estado

State Pattern, también conocido como State Machine Pattern, permite que un objeto cambie su comportamiento mientras cambia su estado interno, haciéndolo parecer una clase modificada.

El comportamiento de la clase en el patrón de estado está determinado por el estado, y los diferentes estados tienen comportamientos diferentes. La intención del patrón de estado es hacer que un objeto cambie su comportamiento junto con él.

El núcleo del patrón de estado es vincular un comportamiento a cada estado.

De acuerdo, el momento de fingir ha llegado de nuevo: hablar es barato, mostrarle el código , primero veamos un ejemplo muy simple.

Ejemplo de patrón de estado

A continuación escribimos un ejemplo sencillo basado en el flujo del estado del pedido. Suponemos que el pedido tiene solo tres estados: por pagar, por recibir y recibido (completado).

1. Primero, cree una clase de estado abstracta, que necesita definir todos los comportamientos de todos los estados:

package com.zwx.design.pattern.state;

public abstract class AbstractOrderState {
    
    
    protected OrderContext orderContext;

    public AbstractOrderState(OrderContext orderContext) {
    
    
        this.orderContext = orderContext;
    }

    public abstract void payOrder();

    public abstract void deliver();

    public abstract void receiveGoods();
}

Tenga en cuenta que integra un objeto OrderContext, que se utiliza para cambiar el estado.

2. Debido a que hay tres estados, creamos tres clases de estado concretas para implementar clases de estado abstractas:

  • Categoría de estado de pago pendiente:
package com.zwx.design.pattern.state;

public class WaitPaidOrderState extends AbstractOrderState {
    
    
    public WaitPaidOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    //相当于待支付的状态绑定了支付行为
        System.out.println("支付成功");
        this.orderContext.setState(this.orderContext.waitDeliver);//切换状态
    }

    @Override
    public void deliver() {
    
    
        System.out.println("对不起,请先付钱");
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("对不起,请先付钱");
    }
}
  • Clase de estado de entrega pendiente:
package com.zwx.design.pattern.state;

public class WaitDeliverOrderState extends AbstractOrderState {
    
    
    public WaitDeliverOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    
        System.out.println("你已经付过钱了");
    }

    @Override
    public void deliver() {
    
    
        System.out.println("商品已发货并送达目的地");
        this.orderContext.setState(this.orderContext.receiveGoods);//切换状态
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("请稍等,商品即将发货");
    }
}
  • Clase de estado recibido:
package com.zwx.design.pattern.state;

public class ReceiveGoodsOrderState extends AbstractOrderState{
    
    
    public ReceiveGoodsOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    
        System.out.println("您已经付过钱啦,不要重复付钱哦");
    }

    @Override
    public void deliver() {
    
    
        System.out.println("商品已发货并送达,请不要重复发货");
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("用户已收到商品,此次交易结束");
    }
}

Podemos ver que cada estado está vinculado a un comportamiento (y también puede admitir enlaces múltiples), y después de que se procese el comportamiento correspondiente, fluirá al siguiente estado y el comportamiento que no pertenece al estado actual se realizará en consecuencia. Respuesta.

3. Cree una clase de entorno de contexto de estado para que sea responsable de cambiar entre estados específicos:

package com.zwx.design.pattern.state;

/**
 * @author zwx
 * @version 1.0
 * @date 2020/10/5
 * @since jdk1.8
 */
public class OrderContext {
    
    
    AbstractOrderState waitPaid;
    AbstractOrderState waitDeliver;
    AbstractOrderState receiveGoods;

    AbstractOrderState currState;//当前状态

    public OrderContext() {
    
    
        this.waitPaid = new WaitPaidOrderState(this);
        this.waitDeliver = new WaitDeliverOrderState(this);
        this.receiveGoods = new ReceiveGoodsOrderState(this);
        currState = waitPaid;
    }

    void setState(AbstractOrderState state){
    
    
        this.currState = state;
    }

    public void payOrder(){
    
    
        currState.payOrder();
    }


    public void deliver(){
    
    
        currState.deliver();
    }

    public void receiveGoods(){
    
    
        currState.receiveGoods();
    }
}

Como puede ver, también hay una sombra del modo de delegación en esta clase, los diferentes comportamientos se delegan a los objetos correspondientes para su procesamiento y solo son responsables del cambio de estado.

4. Finalmente, cree una nueva clase de prueba para probar:

package com.zwx.design.pattern.state;

public class TestState {
    
    
    public static void main(String[] args) {
    
    
        OrderContext orderContext = new OrderContext();
        orderContext.payOrder();
        orderContext.deliver();
        orderContext.receiveGoods();
    }
}

El resultado de salida es:

支付成功
商品已发货并送达目的地
用户已收到商品,此次交易结束

Rol de modo de estado

Del ejemplo anterior, podemos concluir que hay tres roles principales en el modelo de estado:

  • Contexto: define la interfaz requerida por el cliente, mantiene internamente una instancia del estado actual y es responsable del cambio de estados específicos.
  • Rol de estado abstracto (Estado): Defina el comportamiento correspondiente en cada estado, puede haber uno o más comportamientos.
  • Rol de estado concreto (ConcreteState): realice concretamente el comportamiento correspondiente al estado y realice el cambio de estado cuando sea necesario.

Modo de estado y modo de cadena de responsabilidad

Parece que la implementación de este modo de estado es similar al modo de cadena de responsabilidad , que es manejado por una cadena. Se puede decir que los dos modos pueden reemplazarse entre sí en un determinado escenario, pero los dos modos también son esencialmente diferentes.

  • Modo de estado:
    el siguiente nodo del modo de estado ya está comprendido por cada objeto de estado, y la transferencia de estado se lleva a cabo internamente y el cliente no puede decidir.

  • El objeto en el "eslabón" del modelo de cadena de responsabilidad no sabe quién es el siguiente procesador de nodo, pero lo determina el propio cliente.

Modo de estado y modo de estrategia

Tanto el modo de estado como el modo de estrategia se pueden usar para eliminar una gran cantidad de escenarios if / else, pero existen diferencias esenciales. Cada estrategia en el modo de estrategia es independiente y mutuamente reemplazable. Cualquier elección de una estrategia puede satisfacer la demanda, y el cliente toma la decisión. El cliente del modo de estado solo puede seleccionar el nodo inicial, y fluirá automáticamente en el siguiente.Cada estado es un todo y no hay ningún estado que pueda reemplazarse entre sí.

Escenarios de aplicación del modo de estado

Cuando la expresión condicional que controla el estado de un objeto es demasiado complicada, puede considerar usar el modo de estado. Al transferir la lógica de juicio del estado a una serie de clases que representan diferentes estados, puede simplificar la lógica compleja y hacer que el objeto El comportamiento de depende de su estado y cambiará su comportamiento a medida que cambia el estado.
El modo de estado se utiliza principalmente en los siguientes escenarios:

  • 1. Cuando es necesario cambiar el comportamiento del objeto a medida que cambia el estado.
  • 2. Cuando necesitamos escribir una gran cantidad de lógica if / else según el estado de una operación

Ventajas y desventajas del modo estatal

ventaja:

  • 1. Al establecer cada estado como un objeto independiente, se elimina una gran cantidad de ramas if / else en el código, lo que hace que el código sea más conciso y fácil de mantener.
  • 2. Los diferentes estados están representados por diferentes clases, lo que hace que el cambio de estado sea más intuitivo que cuando está representado por números o cadenas, y el propósito de la conversión es más claro.
  • 3. Las responsabilidades de cada clase de estatus son únicas, claras y fáciles de extender.

Desventaja

  • 1. Demasiados estados causarán expansión de clases (de hecho, este también es un problema común en la mayoría de los patrones de diseño).
  • 2. La estructura y la implementación del modo de estado son relativamente complejas, lo que puede causar fácilmente confusión en el código.
  • 3. La clase de estado que admite la conmutación de estado viola el principio de apertura y cierre, porque una vez que se modifica el estado o se debe agregar el estado en el medio, se debe modificar el código fuente correspondiente; de ​​lo contrario, se producirá un error de conmutación de estado.

para resumir

Este artículo presenta principalmente la definición del patrón de estado e implementa un patrón de estado simple a través de un ejemplo simple. Finalmente, el patrón de estado y el patrón de cadena de responsabilidad se comparan y analizan, y se aclara la diferencia entre el patrón de estado y el patrón de cadena de responsabilidad.

Por favor, prestame atención y aprende y progresa con el lobo solitario .

Supongo que te gusta

Origin blog.csdn.net/zwx900102/article/details/109202186
Recomendado
Clasificación