状态模式(State Pattern),当一个对象内在状态改变
时容许其改变行为
,这个对象看起来像改变了其类。简而言之,就是状态的变动引发了行为的变动
。数据库
下图四辆汽车,分别表明汽车平常的四种状态。
开门状态:
this
关门状态:
设计
飞奔状态:
3d
中止状态:
code
其中,某种特定状态下,都有四个可执行操做,分别是open,close,run,stop,而后作对应的处理得下图所示。
对象
类图以下:
blog
CarState
,持有类型为Context
的属性,同时持有四个可执行操做,open
,close
,run
,stop
方法;OpenningState
,ClosingState
,RunningState
,StoppingState
,分别表明开门状态,关门状态,飞奔状态,中止状态;Context
,把状态对象声明为静态常量,有几个状态对象就声明几个静态常量,环境角色具备状态抽象角色定义的全部行为,具体执行使用委托方式。具体环境角色有两个职责:处理本状态必须完成的任务,决定是否能够过渡到其余状态。代码实现以下:get
package com.wzj.state.example1; /** * @Author: wzj * @Date: 2019/11/3 20:10 * @Desc: 汽车状态抽象类 */ public abstract class CarState { //环境角色,封装状态变化引发的行为变化 protected Context context; public void setContext(Context context) { this.context = context; } //汽车开门动做 public abstract void open(); //汽车关门动做 public abstract void close(); //汽车飞奔动做 public abstract void run(); //汽车中止动做 public abstract void stop(); }
package com.wzj.state.example1; /** * @Author: wzj * @Date: 2019/11/3 20:23 * @Desc: 汽车开门状态类 */ public class OpenningState extends CarState { //打开汽车门 public void open() { System.out.println("汽车门已开"); } //关闭汽车门 public void close() { //状态修改 super.context.setCarState(Context.closingState); //动做委托为ClosingState来执行 super.context.getCarState().close(); } //门开着时汽车通常不奔跑 public void run() { System.out.println("汽车开门状态,不能奔跑"); } //车门开着时,切换不到中止状态,由于没有四种状态中,没有开门且中止这个状态 public void stop() { System.out.println("汽车开门状态,不能长时间开着门且处于中止状态"); } }
package com.wzj.state.example1; /** * @Author: wzj * @Date: 2019/11/3 20:23 * @Desc: 汽车飞奔状态类 */ public class RunningState extends CarState { //打开奔跑时不开门 public void open() { System.out.println("车在飞奔,不能打开"); } //奔跑时确定是关门的 public void close() { System.out.println("车在飞奔,已经关闭,不能再次关闭"); } //汽车在飞奔 public void run() { System.out.println("汽车在飞奔"); } //汽车能够停下来 public void stop() { //修改汽车为中止状态 super.context.setCarState(Context.stoppingState); //中止动做委托为StoppingState类来执行 super.context.getCarState().stop(); } }
package com.wzj.state.example1; /** * @Author: wzj * @Date: 2019/11/3 20:23 * @Desc: 汽车关门状态类 */ public class ClosingState extends CarState { //打开汽车门 public void open() { //修改汽车为开门状态 super.context.setCarState(Context.openningState); //动做委托为OpenningState类来执行 super.context.getCarState().open(); } //关闭汽车门 public void close() { System.out.println("汽车门已关"); } //汽车在飞奔 public void run() { //修改汽车为飞奔状态 super.context.setCarState(Context.runningState); //动做委托为RunningState类来执行 super.context.getCarState().run(); } //汽车在中止 public void stop() { //设置汽车状态为中止状态 super.context.setCarState(Context.stoppingState); //动做委托为StoppingState类来执行 super.context.getCarState().stop(); } }
package com.wzj.state.example1; /** * @Author: wzj * @Date: 2019/11/3 20:19 * @Desc: 上下文环境类 */ public class Context { /**列出汽车全部状态 * openningState-开门状态 closingState-关门状态 * runningState-奔驰状态 stoppingState-中止状态 */ public static final OpenningState openningState = new OpenningState(); public static final ClosingState closingState = new ClosingState(); public static final RunningState runningState = new RunningState(); public static final StoppingState stoppingState = new StoppingState(); //定义汽车当前状态 private CarState carState; public CarState getCarState() { return carState; } public void setCarState(CarState carState) { this.carState = carState; //切换状态 this.carState.setContext(this); } //汽车开门 public void open() { this.carState.open(); } //汽车关门 public void close(){ this.carState.close(); } //汽车飞奔 public void run(){ this.carState.run(); } //汽车中止 public void stop(){ this.carState.stop(); } }
客户端类以下:it
package com.wzj.state.example1; /** * @Author: wzj * @Date: 2019/11/3 21:06 * @Desc: */ public class Client { public static void main(String[] args) { Context context = new Context(); context.setCarState(new OpenningState()); // context.setCarState(new ClosingState()); // context.setCarState(new RunningState()); // context.setCarState(new StoppingState()); context.open(); // context.close(); // context.run(); // context.stop(); } }
执行结果以下:
当只打开Client
15行的时候,分别打开11,12,13,14行的代码,会获得以下结果:
汽车为开门状态时,执行open
class
汽车为关门状态时,执行open
汽车为飞奔状态时,执行open
汽车为中止状态时,执行open
上述结果能够看出,一样执行一个open
方法,当状态的变化时致使行为的变化。
优势