设计模式之状态模式

经典案例:任务状态流转的过程

java 复制代码
private String state = StateEnum.INIT.getStateValue();
public String update(ActionEnum actionEnum){

        if (StateEnum.INIT.getStateValue().equals(state)) {
            //初始化 -> 进行中
            if (ActionEnum.START == actionEnum) {
                state = StateEnum.ONGOING.getStateValue();
            }
        } else if (StateEnum.ONGOING.getStateValue().equals(state)) {
            //进行中 -> 已完成   进行中 -> 暂停中   进行中 -> 已过期
            if (actionEnum == ActionEnum.ACHIEVE) {
                state = StateEnum.FINISHED.getStateValue();
            }else if (actionEnum == ActionEnum.STOP){
                state = StateEnum.PAUSED.getStateValue();
            }else if (actionEnum == ActionEnum.EXPIRE){
                state = StateEnum.EXPIRED.getStateValue();
            }
        }else if (StateEnum.PAUSED.getStateValue().equals(state)) {
            //暂停中 -> 进行中   暂停中 -> 已过期
            if (actionEnum == ActionEnum.START) {
                state = StateEnum.ONGOING.getStateValue();
            }else if (actionEnum == ActionEnum.EXPIRE){
                state = StateEnum.EXPIRED.getStateValue();
            }
        }else if (StateEnum.FINISHED.getStateValue().equals(state)) {

        }else if (StateEnum.EXPIRED.getStateValue().equals(state)) {

        }
        return state;
}

不难看出,状态流转的过程使用了大量的if-else做判断,条件复杂或者状态太多时,条件判断语句会过于臃肿,可读性差,且不具备扩展性,维护难度也大。且增加新的状态时要添加新的if-else语句,这违背了开闭原则,不利于程序的扩展。那么可以使用状态模式解决以上的问题,参考美团:设计模式二三事

状态模式:对有状态的对象,把复杂的"判断逻辑"提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。状态模式包含以下主要角色:

  • 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。

  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。

  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

java 复制代码
/**
 * @author maoyouhua
 * @time 2024/3/19
 * @jdkversion jdk21
 * 
 *     枚举类
 */
@AllArgsConstructor
@Getter
public enum ActionEnum {
    START( "开始"),
    STOP("暂停"),
    ACHIEVE("完成"),
    EXPIRE("过期")
    ;

    private final String actionValue;
}
@AllArgsConstructor
@Getter
public enum StateEnum {
    INIT("初始化"),
    ONGOING( "进行中"),
    PAUSED("暂停中"),
    FINISHED("已完成"),
    EXPIRED("已过期")
    ;

    private final String stateValue;

    public String getStateValue() {
        return stateValue;
    }
}
java 复制代码
/**
 * @author maoyouhua
 * @time 2024/3/19
 * @jdkversion jdk21
 *  
 *      抽象状态
 */
public abstract interface State {

    void update(TaskService taskService, ActionEnum actionEnum);
    String getCurrentState();
}
public abstract class AbstractState implements State {

}
java 复制代码
/**
 * @author maoyouhua
 * @time 2024/3/19
 * @jdkversion jdk21
 * 
 *      具体状态
 *      此处有spring循环依赖的问题 需要加配置 spring.main.allow-circular-references=true
 */
@Component
public class InitState extends AbstractState {

    @Autowired
    private OnGoingState onGoingState;
    public static final String stateValue = StateEnum.INIT.getStateValue();
    @Override
    public void update(TaskService taskService, ActionEnum actionEnum) {
        //初始化 -> 进行中
        if (actionEnum == ActionEnum.START) {
            taskService.setTaskState(onGoingState);
        }
    }

    @Override
    public String getCurrentState() {
        return stateValue;
    }
}
@Component
public class OnGoingState extends AbstractState {
    @Autowired
    private FinishedState finishedState;
    @Autowired
    private ExpiredState expiredState;
    @Autowired
    private PausedState pausedState;
    public static final String stateValue = StateEnum.ONGOING.getStateValue();
    @Override
    public void update(TaskService taskService, ActionEnum actionEnum) {
        //进行中 -> 已完成   进行中 -> 暂停中   进行中 -> 已过期
        if (actionEnum == ActionEnum.ACHIEVE) {
            taskService.setTaskState(finishedState);
        }else if (actionEnum == ActionEnum.STOP){
            taskService.setTaskState(pausedState);
        }else if (actionEnum == ActionEnum.EXPIRE){
            taskService.setTaskState(expiredState);
        }
    }

    @Override
    public String getCurrentState() {
        return stateValue;
    }
}
@Component
public class PausedState extends AbstractState {
    @Autowired
    private OnGoingState onGoingState;
    @Autowired
    private ExpiredState expiredState;
    public static final String stateValue = StateEnum.PAUSED.getStateValue();
    @Override
    public void update(TaskService taskService, ActionEnum actionEnum) {
        // 暂停中 -> 进行中      暂停中 -> 已过期
        if (actionEnum == ActionEnum.START) {
            taskService.setTaskState(onGoingState);
        }else if (actionEnum == ActionEnum.EXPIRE){
            taskService.setTaskState(expiredState);
        }
    }

    @Override
    public String getCurrentState() {
        return stateValue;
    }
}
@Component
public class FinishedState extends AbstractState {

    public static final String stateValue = StateEnum.FINISHED.getStateValue();
    @Override
    public void update(TaskService taskService, ActionEnum actionEnum) {}

    @Override
    public String getCurrentState() {
        return stateValue;
    }
}
@Component
public class ExpiredState extends AbstractState {

    public static final String stateValue = StateEnum.EXPIRED.getStateValue();
    @Override
    public void update(TaskService taskService, ActionEnum actionEnum) {}
    @Override
    public String getCurrentState() {
        return stateValue;
    }
}
java 复制代码
/**
 * @author maoyouhua
 * @time 2024/3/19
 * @jdkversion jdk21
 *
 *          多线程不安全
 */
public interface TaskService {
    void updateState(ActionEnum actionEnum);
    State getTaskState();
    void setTaskState(State state);
}
@Component
public class TaskServiceImpl implements TaskService {

    private State state;

    @Autowired
    public TaskServiceImpl(InitState initState) {
        this.state = initState;
    }

    @Override
    public void updateState(ActionEnum actionEnum){
        state.update(this,actionEnum);
    }

    @Override
    public State getTaskState() {
        return state;
    }

    @Override
    public void setTaskState(State state) {
        this.state = state;
    }

}
java 复制代码
/**
 * @author maoyouhua
 * @time 2024/3/19
 * @jdkversion jdk21
 */
@RestController
@RequestMapping("/task")
public class TaskController {
    
    private String state = StateEnum.INIT.getStateValue();

    @Autowired
    private TaskService taskService;

    @RequestMapping("/test")
    public String test(){
        return "任务测试";
    }

    /**
     *
     * @param actionEnum  START、STOP、ACHIEVE、EXPIRE
     * @return
     */
    @RequestMapping("/update")
    public String update(ActionEnum actionEnum){

        if (StateEnum.INIT.getStateValue().equals(state)) {
            //初始化 -> 进行中
            if (ActionEnum.START == actionEnum) {
                state = StateEnum.ONGOING.getStateValue();
            }
        } else if (StateEnum.ONGOING.getStateValue().equals(state)) {
            //进行中 -> 已完成   进行中 -> 暂停中   进行中 -> 已过期
            if (actionEnum == ActionEnum.ACHIEVE) {
                state = StateEnum.FINISHED.getStateValue();
            }else if (actionEnum == ActionEnum.STOP){
                state = StateEnum.PAUSED.getStateValue();
            }else if (actionEnum == ActionEnum.EXPIRE){
                state = StateEnum.EXPIRED.getStateValue();
            }
        }else if (StateEnum.PAUSED.getStateValue().equals(state)) {
            //暂停中 -> 进行中   暂停中 -> 已过期
            if (actionEnum == ActionEnum.START) {
                state = StateEnum.ONGOING.getStateValue();
            }else if (actionEnum == ActionEnum.EXPIRE){
                state = StateEnum.EXPIRED.getStateValue();
            }
        }else if (StateEnum.FINISHED.getStateValue().equals(state)) {

        }else if (StateEnum.EXPIRED.getStateValue().equals(state)) {

        }
        return state;
    }

    @RequestMapping("/updateByStateMode")
    public String updateByStateMode(ActionEnum actionEnum){
        taskService.updateState(actionEnum);
        return taskService.getTaskState().getCurrentState();
    }
}
相关推荐
李广坤11 小时前
状态模式(State Pattern)
设计模式
李广坤12 小时前
观察者模式(Observer Pattern)
设计模式
李广坤13 小时前
中介者模式(Mediator Pattern)
设计模式
李广坤13 小时前
迭代器模式(Iterator Pattern)
设计模式
李广坤14 小时前
解释器模式(Interpreter Pattern)
设计模式
阿无,17 小时前
java23种设计模式之前言
设计模式
Asort17 小时前
JavaScript设计模式(八):组合模式(Composite)——构建灵活可扩展的树形对象结构
前端·javascript·设计模式
数据智能老司机18 小时前
数据工程设计模式——数据基础
大数据·设计模式·架构
nightunderblackcat19 小时前
四大名著智能可视化推演平台
前端·网络·爬虫·python·状态模式
笨手笨脚の20 小时前
设计模式-代理模式
设计模式·代理模式·aop·动态代理·结构型设计模式