状态模式实战运用

目录

前言

UML

plantuml

类图

实战代码

Form

State

Client


前言

通常一个完整的业务流程中,会经历多个阶段,每个阶段即一个业务状态,不同状态下对应这不同的业务处理逻辑。

无脑堆砌 if else 做判断然后选择对应的业务处理其实也能够完成该需求,只不过这样写代码不够优雅。使用状态模式来处理这种业务场景,能让程序可读性更好,易于维护和扩展。

状态模式和策略模式从 UML 上看其实是一样的,很容易混淆。

两者的区别就是策略模式下的策略是由客户端自主选择的,且每个策略之间并没有任何关系;而状态模式下的状态之间是可以互相转换的,每个状态下的行为除了必要的业务处理外,还会涉及到状态转化。

UML

plantuml

@startuml
'https://plantuml.com/class-diagram

interface State {
    + next(Context) : void
    + prev(Context) : void
}

class StateA {
    + next(Context) : void
    + prev(Context) : void
}

class StateB {
    + next(Context) : void
    + prev(Context) : void
}

class Context {
    - state : State
    + Context(State)
    + next() : void
    + prev() : void
}

State <|.. StateA
State <|.. StateB

Context "1" --> "1" State

@enduml

类图

实战代码

业务流程存在三个状态 INIT,PROCESSING,COMPLETE

每个状态可以通过下一步,上一步来进行状态转化

使用枚举类来实现状态模式如下所示

Form

public class Form {
    int state;

    Form() {
        state = 1;
    }

    public int getState() {
        return state;
    }

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

State

public enum State {
    INIT(1, "初始化") {
        public void nextStep(Form form) {
            //其他业务操作
            form.setState(PROCESSING.getValue());
        }

        public void preStep(Form form) {
            throw new RuntimeException("已经是最初状态,无法上一步");
        }
    },
    PROCESSING(2, "处理中") {
        public void nextStep(Form form) {
            //其他业务操作
            form.setState(COMPLETE.getValue());
        }

        public void preStep(Form form) {
            //其他业务操作
            form.setState(INIT.getValue());
        }
    },
    COMPLETE(3, "完成") {
        public void nextStep(Form form) {
            throw new RuntimeException("已经是最终状态,无法下一步");
        }

        public void preStep(Form form) {
            //其他业务操作
            form.setState(COMPLETE.getValue());
        }
    };

    private final Integer value;
    private final String desc;
    private static final Map<Integer, State> map = Arrays.stream(values())
            .collect(toMap(State::getValue, e -> e));

    private State(Integer value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    public Integer getValue() {
        return this.value;
    }

    public String getDesc() {
        return this.desc;
    }

    public void nextStep(Form form) {}

    public void preStep(Form form) {}

    public static State getEnum(Integer value) {
        return map.get(value);
    }
}

Client

public class Client {

    public static void main(String[] args) {
        Form form = new Form();

        State state = State.getEnum(form.getState());
        state.nextStep(form);
        System.out.println(form.getState());

        state = State.getEnum(form.getState());
        state.nextStep(form);
        System.out.println(form.getState());

        state.preStep(form);
        System.out.println(form.getState());
    }
}

相关推荐

  1. 组合模式实战运用

    2024-03-29 07:26:02       44 阅读
  2. 外观模式实战运用

    2024-03-29 07:26:02       46 阅读
  3. 状态模式-C++实现

    2024-03-29 07:26:02       52 阅读
  4. 嵌入式开发中状态模式实现

    2024-03-29 07:26:02       32 阅读
  5. ·状态模式

    2024-03-29 07:26:02       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-29 07:26:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-29 07:26:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-29 07:26:02       82 阅读
  4. Python语言-面向对象

    2024-03-29 07:26:02       91 阅读

热门阅读

  1. python-numpy-常用函数详解

    2024-03-29 07:26:02       38 阅读
  2. 久菜盒子|毕业设计|金融|DCC-GARCH模型

    2024-03-29 07:26:02       42 阅读
  3. OpenCV图像滤波、边缘检测

    2024-03-29 07:26:02       37 阅读
  4. Redis缓存数据库表(列单独缓存)

    2024-03-29 07:26:02       40 阅读
  5. Spring Boot整合Redis

    2024-03-29 07:26:02       38 阅读
  6. 《青少年成长管理2024》 006 “成长需要教育”

    2024-03-29 07:26:02       43 阅读
  7. MyBatis3源码深度解析(二十七)MyBatis整合Spring框架

    2024-03-29 07:26:02       38 阅读