设计模式之状态模式

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

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)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

/**
 * @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;
    }
}
/**
 * @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 {

}
/**
 * @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;
    }
}
/**
 * @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;
    }

}
/**
 * @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();
    }
}

相关推荐

  1. 设计模式状态模式

    2024-03-19 22:08:03       41 阅读
  2. 设计模式状态模式

    2024-03-19 22:08:03       18 阅读
  3. 设计模式状态模式

    2024-03-19 22:08:03       10 阅读
  4. 【前端设计模式状态模式

    2024-03-19 22:08:03       44 阅读
  5. 设计模式状态模式(State Pattern)

    2024-03-19 22:08:03       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-19 22:08:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-19 22:08:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-19 22:08:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-19 22:08:03       20 阅读

热门阅读

  1. web学习笔记(三十九)

    2024-03-19 22:08:03       18 阅读
  2. 服务器硬件基础知识

    2024-03-19 22:08:03       17 阅读
  3. 前端做的轮询小案例- 结合vue2 + nodejs

    2024-03-19 22:08:03       19 阅读
  4. 使用python搭建自己的AI智能问答服务

    2024-03-19 22:08:03       21 阅读
  5. Python使用whisper实现语音识别(ASR)

    2024-03-19 22:08:03       16 阅读
  6. GitHub与Git命令使用笔记

    2024-03-19 22:08:03       21 阅读
  7. JDWP_Event_Composite

    2024-03-19 22:08:03       22 阅读
  8. c++ 自己实现一个迭代器

    2024-03-19 22:08:03       13 阅读
  9. 【Rust】——panic!和不可恢复的错误

    2024-03-19 22:08:03       22 阅读
  10. 深入理解nginx的请求限速模块[下]

    2024-03-19 22:08:03       19 阅读