「这是我参与2022首次更文挑战的第40天,活动详情查看:2022首次更文挑战」。
一、什么是状态模式
状态模式:对于有状态的对象,把不同的状态的判断逻辑提取到不同的状态对象中,允许状态对象在对象状态发生变化时改变其状态。比如有开始,审核中,审核通过几个状态,可以通过建立几个状态对象,出现状态变更时调用相应的状态对象。我们日常生活中常见的红绿灯,洗衣机这些,都有其相应的状态转换。
二、状态模式的实现
public class Context {
private AbstractState state;
public Context() {
this.state = new RedLightState();
}
public void setState(AbstractState state) {
this.state = state;
}
public AbstractState getState() {
return this.state;
}
public void redToGreen() {
state.doNextAction(this);
}
public void GreenToYellow() {
state.doNextAction(this);
}
public void YellowToRed() {
state.doNextAction(this);
}
}
环境类角色,持有状态类,保持当前状态。
public abstract class AbstractState {
protected String lightColor;
public void setLightColor(String lightColor) {
this.lightColor = lightColor;
}
public abstract void doNextAction(Context context);
}
抽象状态角色
public class RedLightState extends AbstractState {
public RedLightState() {
super.lightColor = "Red";
System.out.println("当前为Red");
}
@Override
public void doNextAction(Context context) {
String lightColor = context.getState().lightColor;
System.out.println(lightColor + "变为Green");
if ("Red".equals(lightColor)) {
context.setState(new GreenLightState());
} else {
System.out.println("灯的颜色转换不正确");
}
}
}
具体状态类,当前为红灯,此状态相关的操作是切换为绿灯。
public class GreenLightState extends AbstractState {
public GreenLightState() {
super.lightColor = "Green";
System.out.println("当前为Green");
}
@Override
public void doNextAction(Context context) {
String lightColor = context.getState().lightColor;
System.out.println(lightColor + "变为Yellow");
if ("Green".equals(lightColor)) {
context.setState(new YellowLightState());
} else {
System.out.println("灯的颜色转换不正确");
}
}
}
具体状态类,当前为绿灯,相关操作为切换为黄灯
public class YellowLightState extends AbstractState {
public YellowLightState() {
super.lightColor = "Yellow";
System.out.println("当前为Yellow");
}
@Override
public void doNextAction(Context context) {
String lightColor = context.getState().lightColor;
System.out.println(lightColor + "变为Red");
if ("Yellow".equals(lightColor)) {
context.setState(new RedLightState());
} else {
System.out.println("灯的颜色转换不正确");
}
}
}
具体状态类,当前为黄灯,相关操作为切换为红灯。
public class StateTest {
public static void main(String[] args) {
Context context = new Context();
context.redToGreen();
context.GreenToYellow();
context.YellowToRed();
}
}
通过调用环境中的变换状态的方法,可以方便的完成状态的切换。
三、总结
优点:可以将复杂的if else判断简化为多个状态对象,使得代码结构清晰,状态对象满足单一职责原则。可以方便的扩展新的状态,只需要新增相应状态的子类。
缺点:状态如果越多,状态对象也会相应增多,状态模式的结构较为复杂,相比if else,使用不当会造成代码混乱。
状态模式角色:
- 环境类:内部维持一个状态,负责具体状态的切换。
- 抽象状态类:定义了一个接口,这个接口的作用是在状态切换时,执行与此状态相关的操作,比如红绿灯中的切换灯光的颜色。
- 具体状态角色:实现了抽象状态类,比如红灯态,实现了抽象状态类中的方法,切换灯光颜色为红色。