首页 > 其他分享 >状态模式的理解和实践

状态模式的理解和实践

时间:2024-12-05 22:03:37浏览次数:6  
标签:状态 handle orderContext request 实践 模式 Order 理解 public

        在软件开发中,我们经常遇到需要根据对象的不同状态执行不同行为的情况。如果直接将这些状态判断和行为逻辑写在同一个类中,会导致该类变得臃肿且难以维护。为了解决这个问题,状态模式(State Pattern)应运而生。状态模式是一种行为设计模式,它允许对象在内部状态改变时改变它的行为,避免了大量的条件分支语句,使代码更加清晰和易于管理。

 

一、状态模式的基本概念

        状态模式的核心思想是将对象的行为封装在不同的状态对象中,每个状态对象都有一个共同的抽象状态基类。对象的行为随着其内部状态的改变而改变,而状态的改变是通过状态对象之间的转换来实现的。

        状态模式包含以下几个角色:

  1. Context(环境类):持有当前状态对象的引用,可以维护一个状态对象,并在需要的时候委托状态对象处理请求。
  2. State(抽象状态类):定义一个接口,用于封装与Context的一个特定状态相关的行为。
  3. ConcreteState(具体状态类):实现抽象状态类,每个具体状态类对应Context的一个具体状态,并在其中实现与该状态相关的行为。

二、状态模式的优点

  1. 结构清晰:将状态相关的行为封装在状态类中,避免了大量的条件分支语句,使代码更加清晰。
  2. 易于扩展:新增状态或修改状态行为时,只需新增或修改状态类,无需修改Context类。
  3. 符合开闭原则:对扩展开放,对修改关闭。

三、状态模式的缺点

  1. 类数目增多:状态类数目较多,增加了系统的复杂性。
  2. 状态转换逻辑复杂:如果状态转换逻辑复杂,状态类之间的依赖关系可能会变得复杂。

四、状态模式的实践

        下面我们以一个简单的例子来演示状态模式的应用。假设我们有一个订单系统,订单有不同的状态:待支付、已支付、已发货、已完成。每个状态下订单的行为是不同的,例如待支付状态下可以支付,已支付状态下可以发货,已发货状态下可以确认收货等。

1. 定义抽象状态类

        首先,我们定义一个抽象状态类OrderState,它包含一个处理请求的方法handle

public abstract class OrderState {
    protected OrderContext orderContext;

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

    public abstract void handle(String request);
}


2. 定义具体状态类

        然后,我们为每个状态定义一个具体状态类,例如PendingPaymentStatePaidStateShippedStateCompletedState

public class PendingPaymentState extends OrderState {
    public PendingPaymentState(OrderContext orderContext) {
        super(orderContext);
    }

    @Override
    public void handle(String request) {
        if ("pay".equals(request)) {
            System.out.println("Order is being paid...");
            orderContext.setState(new PaidState(orderContext));
            System.out.println("Order has been paid.");
        } else {
            System.out.println("Invalid request for this state: " + request);
        }
    }
}

public class PaidState extends OrderState {
    public PaidState(OrderContext orderContext) {
        super(orderContext);
    }

    @Override
    public void handle(String request) {
        if ("ship".equals(request)) {
            System.out.println("Order is being shipped...");
            orderContext.setState(new ShippedState(orderContext));
            System.out.println("Order has been shipped.");
        } else {
            System.out.println("Invalid request for this state: " + request);
        }
    }
}

public class ShippedState extends OrderState {
    public ShippedState(OrderContext orderContext) {
        super(orderContext);
    }

    @Override
    public void handle(String request) {
        if ("confirm".equals(request)) {
            System.out.println("Order is being confirmed...");
            orderContext.setState(new CompletedState(orderContext));
            System.out.println("Order has been completed.");
        } else {
            System.out.println("Invalid request for this state: " + request);
        }
    }
}

public class CompletedState extends OrderState {
    public CompletedState(OrderContext orderContext) {
        super(orderContext);
    }

    @Override
    public void handle(String request) {
        System.out.println("Order is already completed. No further actions can be taken.");
    }
}


3. 定义环境类

        接下来,我们定义环境类OrderContext,它持有当前状态对象的引用,并在需要的时候委托状态对象处理请求。

public class OrderContext {
    private OrderState state;

    public OrderContext() {
        this.state = new PendingPaymentState(this);
    }

    public void setState(OrderState state) {
        this.state = state;
    }

    public void handle(String request) {
        state.handle(request);
    }

    public static void main(String[] args) {
        OrderContext orderContext = new OrderContext();

        orderContext.handle("pay");
        orderContext.handle("ship");
        orderContext.handle("confirm");
        orderContext.handle("confirm"); // Invalid request for this state
    }
}


4. 运行结果

        运行OrderContextmain方法,输出结果如下:

Order is being paid...
Order has been paid.
Order is being shipped...
Order has been shipped.
Order is being confirmed...
Order has been completed.
Invalid request for this state: confirm


总结

        状态模式通过将对象的行为封装在不同的状态对象中,使对象的行为随着其内部状态的改变而改变。状态模式避免了大量的条件分支语句,使代码更加清晰和易于维护。同时,状态模式也符合开闭原则,对扩展开放,对修改关闭。

        在实际应用中,状态模式适用于对象的行为依赖于其状态,并且状态之间可以相互转换的场景。例如,订单处理系统、工作流引擎、游戏角色状态管理等。

        需要注意的是,状态模式会增加类的数目,并且如果状态转换逻辑复杂,状态类之间的依赖关系可能会变得复杂。因此,在使用状态模式时,需要权衡其优缺点,根据具体场景选择合适的设计模式。

标签:状态,handle,orderContext,request,实践,模式,Order,理解,public
From: https://blog.csdn.net/huaqianzkh/article/details/144250381

相关文章

  • 责任链模式的理解和实践
            责任链模式(ChainofResponsibility)是行为型设计模式之一,它通过将多个对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止。这个模式的主要目的是将请求的发送者和接收者解耦,使请求沿着处理链传递,直到被某个对象处理。本文将详细介绍责任链模式的理解和......
  • 解释器模式的理解和实践
    引言        解释器模式(InterpreterPattern)是一种行为型设计模式,它在软件工程中用得相对较少,但在某些特定场景下非常有用。解释器模式提供了一种解释语言的语法或表达式的方式,它定义了一个表达式接口,并通过该接口解释一个特定的上下文。通过解释器模式,你可以构建一个......
  • Lambda表达式和函数式接口的最佳实践
    Java8引入了Lambda表达式和函数式接口,这一改变不仅极大地简化了代码的编写,还提升了代码的可读性和可维护性。Lambda表达式可以被看作一种匿名函数,它能够作为参数传递给方法或存储在变量中。本文将深入探讨Lambda表达式和函数式接口在实际应用中的最佳实践。Lambda表达式的......
  • 你对Collection中Set、List、Map理解?
    @目录一、图二、hashMap1.扩容算法2.ConcurrentHashMap原理3.TreeMap红黑树特性?使用好处?4.LinkedHashMap的特点?数据结构?三、HashMap底层实现原理及面试问题一、图二、hashMap1.扩容算法所以说,当数组长度为2的n次幂的时候,不同的key算得得index相同的几率较小,那么数据在数组上......
  • 解题报告-论对“区间可持久化”的新理解
    解题报告-论对“区间可持久化”的新理解当我第一眼看到“可持久化\(\texttt{Trie}\)”的时候,我以为这不过是一个\(\texttt{Trie}\)+可持久化罢了。事实证明也是这样,在后面的代码实现中,我也是一遍打对了这个紫色板子。那么,一道模板题,有什么好说的?正是因为控住我的不是模板,这道......
  • 15 设计模式之抽象工厂模式(支付系统案例)
    一、什么是抽象工厂模式        抽象工厂模式(AbstractFactoryPattern)是创建型设计模式之一,用于提供一个接口,用来创建一系列相关或相互依赖的对象,而不需要指定它们具体的类。        抽象工厂模式允许客户端通过工厂接口来创建一系列相关的产品对象,而无需知......
  • 软件设计:实验 25:访问者模式
    实验25:访问者模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解访问者模式的动机,掌握该模式的结构;2、能够利用访问者模式法解决实际问题。 [实验任务一]:打包员在我们课堂上的“购物车”的例子中,增加一个新的访问者:打包员,负责对购物车中货物装包。实验要......
  • 深入理解Java动态代理:从传统实现到动态代理的演变
    深入理解Java动态代理:从传统实现到动态代理的演变引言在面向对象编程中,代理模式是一种设计模式,它允许为其他对象提供一种代理以控制对这个对象的访问。Java中的动态代理提供了无需修改源代码即可增强方法行为的能力,这在AOP(面向切面编程)和框架开发中尤为重要。本文将通过一个用户......
  • AIGC项目中的【模板进程】方案的设计实践
    1项目介绍1.1项目背景简单一句话:模板进程是流程的子流程;往往用于比较复杂的aigc项目流程中。由于一个模板有多个流程,一个运营人员可以操作多个流程,也可创建多个流程。在模板推荐时,就会导致不知道是哪次流程。1.2项目目标为了区分模板中流程,就需要增加进程的概念(子流程),为了......
  • C++对象模型实践探索
    前言C++对象模型是个常见、且复杂的话题,本文基于ItaniumC++ABI通过程序实践介绍了几种简单C++继承场景下对象模型,尤其是存在虚函数的场景,并通过图的方式直观表达内存布局。本文展示的程序构建环境为Ubuntu,glibc2.24,gcc6.3.0。由于clang和gcc编译器都是基于ItaniumC++......