目录
前言
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());
}
}