那个网站百度收录快,装修设计软件排名,网站建设三把火科技,精品网站开发公司一、什么是状态模式 什么是状态模式呢#xff0c;这里我举一个例子来说明#xff0c;在自动挡汽车中#xff0c;挡位的切换是根据驾驶条件#xff08;如车速、油门踏板位置、刹车状态等#xff09;自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式…一、什么是状态模式 什么是状态模式呢这里我举一个例子来说明在自动挡汽车中挡位的切换是根据驾驶条件如车速、油门踏板位置、刹车状态等自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式State Pattern 是一种行为型设计模式它允许一个对象在其内部状态发生变化时加速或者减速改变其行为换挡。状态模式的核心思想是将对象的行为封装在不同的状态类中使得对象的行为随着状态的改变而改变。这种模式特别适用于对象的行为依赖于其内部状态的场景。
二、为什么使用状态模式 清晰的职责划分代码结构清晰每个状态类的职责单一易于理解和维护。例如在自动挡汽车中每个挡位的行为都封装在独立的状态类中职责划分明确。 动态改变行为减少了复杂的条件分支如 if-else 或 switch-case使代码更加简洁和可读。例如在自动挡汽车中换挡逻辑由状态机自动处理无需在主逻辑中写复杂的条件判断。 扩展性符合开闭原则对扩展开放对修改封闭。例如在自动挡汽车中新增一个挡位如6挡时只需添加一个新的状态类无需修改现有的换挡逻辑。 低耦合状态类和上下文类之间的依赖关系减少提高了代码的灵活性和可维护性。例如在自动挡汽车中Car 类与各个挡位状态类通过 GearState 接口交互降低了耦合度。 适应复杂状态逻辑能够清晰地表达状态转换逻辑避免代码混乱。例如在自动挡汽车中换挡逻辑可能涉及多种条件如车速、油门位置等状态机模式能够清晰地表达这些逻辑。
三、状态模式的示例
3.1 状态模式示例及角色
1. State定义状态接口行为
定义了所有挡位状态的通用接口包含所有挡位共有的方法例如加速、减速等
public interface GearState {void accelerate(Car car); // 加速时的行为void decelerate(Car car); // 减速时的行为
}
2. ConcreteState实现具体状态类(档位)
每个挡位如1挡、2挡、3挡、4挡、5挡等都实现状态接口并定义在该挡位下的行为。
public class FirstGear implements GearState {Overridepublic void accelerate(Car car) {System.out.println(当前1档加速...);car.setState(new SecondGear()); // 切换到2挡}Overridepublic void decelerate(Car car) {System.out.println(当前1档减速...);car.setState(new NeutralGear()); // 切换到空挡}
}public class SecondGear implements GearState {Overridepublic void accelerate(Car car) {System.out.println(当前2档加速...);car.setState(new ThirdGear()); // 切换到3挡}Overridepublic void decelerate(Car car) {System.out.println(当前2档减速...);car.setState(new FirstGear()); // 切换到1挡}
}public class ThirdGear implements GearState {Overridepublic void accelerate(Car car) {System.out.println(当前3档加速...);car.setState(new FourthGear()); // 切换到4挡}Overridepublic void decelerate(Car car) {System.out.println(当前3档减速...);car.setState(new SecondGear()); // 切换到2挡}
}public class FourthGear implements GearState {Overridepublic void accelerate(Car car) {System.out.println(当前4档加速...);car.setState(new FifthGear()); // 切换到5挡}Overridepublic void decelerate(Car car) {System.out.println(当前1档减速...);car.setState(new ThirdGear()); // 切换到3挡}
}public class FifthGear implements GearState {Overridepublic void accelerate(Car car) {System.out.println(当前5档加速...);// 保持在5挡}Overridepublic void decelerate(Car car) {System.out.println(当前5档减速...);car.setState(new FourthGear()); // 切换到4挡}
}public class NeutralGear implements GearState {Overridepublic void accelerate(Car car) {System.out.println(当前空档加速...);car.setState(new FirstGear()); // 切换到1挡}Overridepublic void decelerate(Car car) {System.out.println(当前空档减速...);// 保持在空挡}
}
3、Context上下文当前车辆记录当前状态
上下文可以被视为汽车的驾驶系统它包含当前挡位的状态并根据驾驶员的操作切换挡位
public class Car {private GearState currentState;public Car() {this.currentState new NeutralGear(); // 初始状态为空挡}public void setState(GearState state) {this.currentState state;}public void accelerate() {currentState.accelerate(this);}public void decelerate() {currentState.decelerate(this);}
}
4、场景开车
public class Main {public static void main(String[] args) {Car car new Car();car.accelerate(); // 初始状态为空挡加速后切换到1挡car.accelerate(); // 当前状态为1挡加速后切换到2挡car.accelerate(); // 当前状态为2挡加速后切换到3挡car.decelerate(); // 当前状态为3挡减速后切换到2挡car.decelerate(); // 当前状态为2挡减速后切换到1挡car.decelerate(); // 当前状态为1挡减速后切换到空挡}
}//输出
当前0档加速...
当前1档加速...
当前2档加速...
当前3档加速...
当前3档减速...
当前2档减速...
当前1档减速...
当前0档减速...
3.2 在JAVA开发中常用的Spring状态机 在Spring框架中可以使用Spring State Machine来实现状态机模式。Spring State Machine是一个功能强大的状态机框架支持定义状态、事件和状态转换并且可以与Spring生态系统无缝集成。在实际开发中可能使用Spring框架比较多一般都是直接使用现成的Spring State Machine 来实现状态模式。
1、集成依赖包
dependencygroupIdorg.springframework.statemachine/groupIdartifactIdspring-statemachine-core/artifactIdversion2.1.3.RELEASE/version
/dependency
2、定义状态和事件
//车辆档位枚举类
public enum CarState {NEUTRAL, //空挡FIRST_GEAR, //一档SECOND_GEAR, //二挡THIRD_GEAR, //三挡FOURTH_GEAR, //四挡FIFTH_GEAR; //五档
}//车辆行为枚举类
public enum CarEvent {ACCELERATE, //加速行为DECELERATE; //减速行为
}
3、配置状态机
Configuration
EnableStateMachine(namecarStateMachine)
public class CarStateMachineConfig extends StateMachineConfigurerAdapterCarState, CarEvent {public void configure(StateMachineStateConfigurerCarState, CarEvent states) throws Exception {states.withStates().initial(CarState.NEUTRAL).states(EnumSet.allOf(CarState.class));}Overridepublic void configure(StateMachineTransitionConfigurerCarState, CarEvent states) throws Exception {states.withExternal().source(CarState.NEUTRAL).target(CarState.FIRST_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.FIRST_GEAR).target(CarState.SECOND_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.SECOND_GEAR).target(CarState.THIRD_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.THIRD_GEAR).target(CarState.FOURTH_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.FOURTH_GEAR).target(CarState.FIFTH_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.FIFTH_GEAR).event(CarEvent.ACCELERATE) // No change.and().withExternal().source(CarState.FIFTH_GEAR).target(CarState.FOURTH_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.FOURTH_GEAR).target(CarState.THIRD_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.THIRD_GEAR).target(CarState.SECOND_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.SECOND_GEAR).target(CarState.FIRST_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.FIRST_GEAR).target(CarState.NEUTRAL).event(CarEvent.DECELERATE);}// 配置状态机持久化Beanpublic DefaultStateMachinePersister machinePersister() {return new DefaultStateMachinePersister(new StateMachinePersistObject, Object, Car() {Overridepublic void write(StateMachineContextObject, Object stateMachineContext, Car car) throws Exception {//持久化操作。可以通过任何形式进行持久化。redis 、 mongodb、mysqlecache}Overridepublic StateMachineContextObject, Object read(Car car) throws Exception {// 从持久化组件里进行读取return new DefaultStateMachineContext(car.getCarState(), null, null, null);}});}
}
4、定义状态监听器 在Spring State Machine中可以通过WithStateMachine注解和OnTransition注解来定义状态监听器。这些监听器会在状态转换时被触发。
// 监听器是监听到 action 后进行状态的一个变更。
Slf4j
Component(carStateListener)
WithStateMachine(namecarStateMachine)
public class CarStateListener {OnTransition(source NEUTRAL, target FIRST_GEAR)public boolean onAccelerateFromNeutral(MessageCarEvent message) {log.info(Accelerating from NEUTRAL to FIRST_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.FIRST_GEAR);return true;}OnTransition(source FIRST_GEAR, target SECOND_GEAR)public boolean onAccelerateFromFirstGear(MessageCarEvent message) {log.info(Accelerating from FIRST_GEAR to SECOND_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.SECOND_GEAR);return true;}OnTransition(source SECOND_GEAR, target THIRD_GEAR)public boolean onAccelerateFromSecondGear(MessageCarEvent message) {log.info(Accelerating from SECOND_GEAR to THIRD_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.THIRD_GEAR);return true;}OnTransition(source THIRD_GEAR, target FOURTH_GEAR)public boolean onAccelerateFromThirdGear(MessageCarEvent message) {log.info(Accelerating from THIRD_GEAR to FOURTH_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.FOURTH_GEAR);return true;}OnTransition(source FOURTH_GEAR, target FIFTH_GEAR)public boolean onAccelerateFromFourthGear(MessageCarEvent message) {log.info(Accelerating from FOURTH_GEAR to FIFTH_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.FIFTH_GEAR);return true;}OnTransition(source FIFTH_GEAR, target FOURTH_GEAR)public boolean onDecelerateFromFifthGear(MessageCarEvent message) {log.info(Decelerating from FIFTH_GEAR to FOURTH_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.FOURTH_GEAR);return true;}OnTransition(source FOURTH_GEAR, target THIRD_GEAR)public boolean onDecelerateFromFourthGear(MessageCarEvent message) {log.info(Decelerating from FOURTH_GEAR to THIRD_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.THIRD_GEAR);return true;}OnTransition(source THIRD_GEAR, target SECOND_GEAR)public boolean onDecelerateFromThirdGear(MessageCarEvent message) {log.info(Decelerating from THIRD_GEAR to SECOND_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.SECOND_GEAR);return true;}OnTransition(source SECOND_GEAR, target FIRST_GEAR)public boolean onDecelerateFromSecondGear(MessageCarEvent message) {log.info(Decelerating from SECOND_GEAR to FIRST_GEAR);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.FIRST_GEAR);return true;}OnTransition(source FIRST_GEAR, target NEUTRAL)public boolean onDecelerateFromFirstGear(MessageCarEvent message) {log.info(Decelerating from FIRST_GEAR to NEUTRAL);Car car (Car) message.getHeaders().get(car);car.setCarState(CarState.NEUTRAL);return true;}}
4、使用状态机
Service
public class CarService {Resourceprivate StateMachineCarState, CarEvent carStateMachine;Resourceprivate StateMachinePersisterCarState, CarEvent, Car carMachinePersister;//模拟一个存储private Car car new Car();//加速方法public Car acc() {if (car.getCarState() null){car.setCarState(CarState.NEUTRAL);}// 书写逻辑Message message MessageBuilder.withPayload(CarEvent.ACCELERATE).setHeader(car, car).build();if(changeStateAction(message,car)) {return car;}return car;}//减速方法public Car dece() {if (car.getCarState() null){car.setCarState(CarState.NEUTRAL);}// 书写逻辑Message message MessageBuilder.withPayload(CarEvent.DECELERATE).setHeader(car, car).build();if(changeStateAction(message,car)) {return car;}return car;}private boolean changeStateAction(MessageCarEvent message, Car car) {try {carStateMachine.start();//尝试恢复状态机状态carMachinePersister.restore(carStateMachine, car); // 待议boolean res carStateMachine.sendEvent(message);//持久化状态机状态carMachinePersister.persist(carStateMachine, car); // 持久return res;} catch (Exception e) {e.printStackTrace();} finally {carStateMachine.stop();}return false;}
}
4、场景开车
SpringBootApplication
public class CarApplication {public static void main(String[] args) {ConfigurableApplicationContext context SpringApplication.run(DesignApplication.class, args);CarService carService context.getBean(CarService.class);Car car;car carService.acc(); // 初始状态为空挡加速后切换到1挡System.out.println(After accelerate: car.getCarState());car carService.acc(); // 当前状态为1挡加速后切换到2挡System.out.println(After accelerate: car.getCarState());car carService.dece(); // 当前状态为2挡减速后切换到1挡System.out.println(After decelerate: car.getCarState());car carService.dece(); // 当前状态为1挡减速后切换到空挡System.out.println(After decelerate: car.getCarState());}
}//输出
After accelerate: FIRST_GEAR
After accelerate: SECOND_GEAR
After decelerate: FIRST_GEAR
After decelerate: NEUTRAL 文章转载自: http://www.morning.rnzwh.cn.gov.cn.rnzwh.cn http://www.morning.stbhn.cn.gov.cn.stbhn.cn http://www.morning.tslwz.cn.gov.cn.tslwz.cn http://www.morning.zmpqt.cn.gov.cn.zmpqt.cn http://www.morning.dxsyp.cn.gov.cn.dxsyp.cn http://www.morning.deupp.com.gov.cn.deupp.com http://www.morning.qgwpx.cn.gov.cn.qgwpx.cn http://www.morning.nlcw.cn.gov.cn.nlcw.cn http://www.morning.rdkgw.cn.gov.cn.rdkgw.cn http://www.morning.kcxtz.cn.gov.cn.kcxtz.cn http://www.morning.mjtgt.cn.gov.cn.mjtgt.cn http://www.morning.pqndg.cn.gov.cn.pqndg.cn http://www.morning.rxlck.cn.gov.cn.rxlck.cn http://www.morning.gjfym.cn.gov.cn.gjfym.cn http://www.morning.hxbjt.cn.gov.cn.hxbjt.cn http://www.morning.zdbfl.cn.gov.cn.zdbfl.cn http://www.morning.fxjnn.cn.gov.cn.fxjnn.cn http://www.morning.xnpml.cn.gov.cn.xnpml.cn http://www.morning.ynlpy.cn.gov.cn.ynlpy.cn http://www.morning.llyqm.cn.gov.cn.llyqm.cn http://www.morning.dmzzt.cn.gov.cn.dmzzt.cn http://www.morning.smkxm.cn.gov.cn.smkxm.cn http://www.morning.gnghp.cn.gov.cn.gnghp.cn http://www.morning.szzxqc.com.gov.cn.szzxqc.com http://www.morning.lkcqz.cn.gov.cn.lkcqz.cn http://www.morning.wmhqd.cn.gov.cn.wmhqd.cn http://www.morning.rksg.cn.gov.cn.rksg.cn http://www.morning.qsy36.cn.gov.cn.qsy36.cn http://www.morning.syrzl.cn.gov.cn.syrzl.cn http://www.morning.xxlz.cn.gov.cn.xxlz.cn http://www.morning.nhzps.cn.gov.cn.nhzps.cn http://www.morning.fpqq.cn.gov.cn.fpqq.cn http://www.morning.xtgzp.cn.gov.cn.xtgzp.cn http://www.morning.ummpdl.cn.gov.cn.ummpdl.cn http://www.morning.cbczs.cn.gov.cn.cbczs.cn http://www.morning.jthjr.cn.gov.cn.jthjr.cn http://www.morning.ypklb.cn.gov.cn.ypklb.cn http://www.morning.tllws.cn.gov.cn.tllws.cn http://www.morning.ljfjm.cn.gov.cn.ljfjm.cn http://www.morning.xxzjb.cn.gov.cn.xxzjb.cn http://www.morning.ysrtj.cn.gov.cn.ysrtj.cn http://www.morning.hcszr.cn.gov.cn.hcszr.cn http://www.morning.dnls.cn.gov.cn.dnls.cn http://www.morning.fkgqn.cn.gov.cn.fkgqn.cn http://www.morning.wyppp.cn.gov.cn.wyppp.cn http://www.morning.xqbgm.cn.gov.cn.xqbgm.cn http://www.morning.gqwpl.cn.gov.cn.gqwpl.cn http://www.morning.qmzhy.cn.gov.cn.qmzhy.cn http://www.morning.mspqw.cn.gov.cn.mspqw.cn http://www.morning.kfsfm.cn.gov.cn.kfsfm.cn http://www.morning.nfcxq.cn.gov.cn.nfcxq.cn http://www.morning.mqbsm.cn.gov.cn.mqbsm.cn http://www.morning.mmxnb.cn.gov.cn.mmxnb.cn http://www.morning.dodoking.cn.gov.cn.dodoking.cn http://www.morning.ltcnd.cn.gov.cn.ltcnd.cn http://www.morning.pwwjs.cn.gov.cn.pwwjs.cn http://www.morning.jhgxh.cn.gov.cn.jhgxh.cn http://www.morning.qrmyd.cn.gov.cn.qrmyd.cn http://www.morning.mnqg.cn.gov.cn.mnqg.cn http://www.morning.gryzk.cn.gov.cn.gryzk.cn http://www.morning.gjzwj.cn.gov.cn.gjzwj.cn http://www.morning.bqxxq.cn.gov.cn.bqxxq.cn http://www.morning.ngmjn.cn.gov.cn.ngmjn.cn http://www.morning.wcghr.cn.gov.cn.wcghr.cn http://www.morning.ptysj.cn.gov.cn.ptysj.cn http://www.morning.jgykx.cn.gov.cn.jgykx.cn http://www.morning.jbxfm.cn.gov.cn.jbxfm.cn http://www.morning.kpbgp.cn.gov.cn.kpbgp.cn http://www.morning.zlfxp.cn.gov.cn.zlfxp.cn http://www.morning.stflb.cn.gov.cn.stflb.cn http://www.morning.mnygn.cn.gov.cn.mnygn.cn http://www.morning.bssjp.cn.gov.cn.bssjp.cn http://www.morning.qmfhh.cn.gov.cn.qmfhh.cn http://www.morning.sfqtf.cn.gov.cn.sfqtf.cn http://www.morning.fgqbx.cn.gov.cn.fgqbx.cn http://www.morning.cfnsn.cn.gov.cn.cfnsn.cn http://www.morning.bryyb.cn.gov.cn.bryyb.cn http://www.morning.glbnc.cn.gov.cn.glbnc.cn http://www.morning.qsswb.cn.gov.cn.qsswb.cn http://www.morning.rzczl.cn.gov.cn.rzczl.cn