目录
前言
UML
plantuml
类图
实战代码
Form
State
Client
前言
通常一个完整的业务流程中,会经历多个阶段,每个阶段即一个业务状态,不同状态下对应这不同的业务处理逻辑。
无脑堆砌 if else 做判断然后选择对应的业务处理其实也能够完成该需求,只不过这样写代码不够优雅。使用状态模式来处理这种业务场景,能让程序可读性更好,易于维护和扩展。
状态模式和策略模式从 UML 上看其实是一样的,很容易混淆。
两者的区别就是策略模式下的策略是由客户端自主选择的,且每个策略之间并没有任何关系;而状态模式下的状态之间是可以互相转换的,每个状态下的行为除了必要的业务处理外,还会涉及到状态转化。
UML
plantuml
@startuml 'https://plantuml.com/class-diagraminterface 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 <|.. StateBContext "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());}
}