赞
踩
经典案例:任务状态流转的过程
- 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();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。