设计模式-状态模式

状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在内部状态发生改变时,改变其行为。状态模式将状态的逻辑封装到独立的状态类中,避免了使用大量的条件语句(如 if-elseswitch-case),从而使代码更加清晰、灵活和可扩展。


状态模式的组成部分:

  1. 上下文(Context)
    • 定义了客户端所需要的接口,并维护一个当前状态的引用,用于切换状态。
  2. 抽象状态(State)
    • 定义了一个接口,封装与上下文相关的行为。
  3. 具体状态(ConcreteState)
    • 实现了抽象状态的具体行为,每个类代表一种状态,并负责实现与该状态相关的行为。

示例代码:文档审批流程

问题背景

假设有一个文档审批系统,文档的状态有以下几种:

  • 草稿状态(Draft):可以编辑和提交。
  • 审核中状态(UnderReview):只能撤回。
  • 发布状态(Published):无法编辑或提交。

文档的行为(如编辑、提交、撤回等)会根据当前状态的不同而表现出不同的行为。


实现代码

// 抽象状态
interface State {
    void edit(Document context);   // 编辑文档
    void submit(Document context); // 提交文档
    void revoke(Document context); // 撤回文档
}

// 具体状态:草稿状态
class DraftState implements State {
    @Override
    public void edit(Document context) {
        System.out.println("文档正在编辑...");
    }

    @Override
    public void submit(Document context) {
        System.out.println("文档已提交,进入审核状态。");
        context.setState(new UnderReviewState());
    }

    @Override
    public void revoke(Document context) {
        System.out.println("草稿状态下无法撤回文档!");
    }
}

// 具体状态:审核中状态
class UnderReviewState implements State {
    @Override
    public void edit(Document context) {
        System.out.println("审核中,无法编辑文档!");
    }

    @Override
    public void submit(Document context) {
        System.out.println("文档已提交,不能重复提交!");
    }

    @Override
    public void revoke(Document context) {
        System.out.println("审核中,文档已撤回到草稿状态。");
        context.setState(new DraftState());
    }
}

// 具体状态:发布状态
class PublishedState implements State {
    @Override
    public void edit(Document context) {
        System.out.println("文档已发布,无法编辑!");
    }

    @Override
    public void submit(Document context) {
        System.out.println("文档已发布,无法提交!");
    }

    @Override
    public void revoke(Document context) {
        System.out.println("文档已发布,无法撤回!");
    }
}

// 上下文类:文档
class Document {
    private State state; // 当前状态

    public Document() {
        // 初始状态为草稿
        this.state = new DraftState();
    }

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

    // 调用当前状态的方法
    public void edit() {
        state.edit(this);
    }

    public void submit() {
        state.submit(this);
    }

    public void revoke() {
        state.revoke(this);
    }
}

// 客户端
public class StatePatternExample {
    public static void main(String[] args) {
        Document document = new Document();

        // 草稿状态
        document.edit();
        document.submit();

        // 审核中状态
        document.edit();
        document.revoke();

        // 回到草稿状态
        document.edit();
        document.submit();

        // 审核中状态提交成功
        document.submit();

        // 发布状态
        document.revoke();
    }
}

输出结果:

文档正在编辑...
文档已提交,进入审核状态。
审核中,无法编辑文档!
审核中,文档已撤回到草稿状态。
文档正在编辑...
文档已提交,进入审核状态。
文档已提交,不能重复提交!
文档已发布,无法撤回!

状态模式的优点:

  1. 清晰的状态转换
    • 将状态逻辑封装在独立的状态类中,避免了在上下文类中使用复杂的条件语句。
  2. 扩展性强
    • 可以轻松添加新的状态或修改现有状态,而无需修改上下文类的代码。
  3. 符合单一职责原则
    • 每个状态类只关注与其对应的状态相关的行为。

状态模式的缺点:

  1. 增加了类的数量
    • 每个状态都需要定义一个类,可能导致类的数量增加。
  2. 状态之间的耦合性
    • 状态类之间可能需要切换状态,这会引入一定的耦合性。

状态模式的适用场景:

  1. 对象的行为依赖于状态,并且状态会在运行时发生改变
  2. 避免条件语句(如 if-elseswitch-case)导致代码复杂度增加
  3. 希望通过改变状态来改变对象行为,而不影响对象的其他部分

状态模式常用于工作流系统、游戏角色状态管理、设备操作状态等场景中。

posted @   庞某人  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示