设计模式之管理状态_Status状态模式_用类保存状态
前言
博主github
博主个人博客http://blog.healerjean.com
1、解释
1、对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2、代码中包含大量与对象状态有关的条件语句:一个操作中含有庞大的多条件(if else 或switch case)语句,且这些条件依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。
//运行动作
@Override
public void run() {
switch (state) {
case OPEN_STATE:
System.out.println("处于开门状态:什么也不做");
break;
case CLOSE_STATE:
System.out.println("处于关门状态:运行...");
setState(RUN_STATE);
break;
case RUN_STATE:
System.out.println("处于运行状态:什么也不做");
break;
case STOP_STATE:
System.out.println("处于停止状态:运行...");
setState(RUN_STATE);
}
}
通常 , 有多个操作包含这一相同的条件结构。 State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
1.1、状态抽象类
public abstract class LiftState {
/**
* 定义一个环境角色,也就是封装状态的变换引起的功能变化
*/
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();
}
1.2、电梯Opening子类
public class OpenningState extends LiftState {
@Override
public void open() {
System.out.println("电梯门开启...");
}
@Override
public void close() {
System.out.println("电梯准备从Openning状态到Closeing状态");
super.context.setLiftState(Context.closeingState);
super.context.getLiftState().close();
}
@Override
public void run() {
throw new RuntimeException("电梯在门开启下就是不可以运行,容易发生危险");
}
@Override
public void stop() {
throw new RuntimeException("电梯在门开启下就是停止状态,无须操作");
}
}
1.3、电梯Closing
package com.hlj.moudle.design.D08管理状态.D19Status状态模式;
/**
* @author HealerJean
* @ClassName ClosingState
* @date 2019-08-20 21:29.
* @Description 电梯门关闭以后,电梯可以做哪些事情
*/
public class ClosingState extends LiftState {
@Override
public void open() {
System.out.println("电梯准备从Closing状态到Opening状态");
super.context.setLiftState(Context.openningState);
super.context.getLiftState().open();
}
/**
* 电梯门关闭,这是关闭状态要实现的动作
*/
@Override
public void close() {
System.out.println("电梯门关闭...");
}
@Override
public void run() {
System.out.println("电梯准备从Closing状态到Runing状态");
super.context.setLiftState(Context.runningState);
super.context.getLiftState().run();
}
@Override
public void stop() {
System.out.println("电梯准备从Closing状态到Stoping状态");
super.context.setLiftState(Context.stoppingState);
super.context.getLiftState().stop();
}
}
1.4、电梯RunningState子类
package com.hlj.moudle.design.D08管理状态.D19Status状态模式;
/**
* @author HealerJean
* @ClassName RunningState
* @date 2019-08-20 21:30.
* @Description电梯在运行状态下能做哪些动作
*/
public class RunningState extends LiftState {
@Override
public void open() {
throw new RuntimeException("电梯在运行状态下门不可以打开");
}
@Override
public void close() {
throw new RuntimeException("电梯在运行状态下门肯定是关闭的");
}
@Override
public void run() {
System.out.println("电梯正在开始跑…………………………");
}
@Override
public void stop() {
System.out.println("电梯准备从Running状态到Stoping状态");
super.context.setLiftState(Context.stoppingState);
super.context.getLiftState().stop();
}
}
1.5、电梯StoppingState子类
package com.hlj.moudle.design.D08管理状态.D19Status状态模式;
/**
* @author HealerJean
* @ClassName StoppingState
* @date 2019-08-20 21:31.
* @Description 在停止状态下能做什么事情
*/
public class StoppingState extends LiftState {
@Override
public void open() {
System.out.println("电梯准备从Stopping状态到Opening状态");
super.context.setLiftState(Context.openningState);
super.context.getLiftState().open();
}
@Override
public void close() {
throw new RuntimeException("电梯停止状态下们就是关闭的");
}
@Override
public void run() {
System.out.println("电梯准备从Stopping状态到Running状态");
super.context.setLiftState(Context.runningState);
super.context.getLiftState().run();
}
@Override
public void stop() {
System.out.println("电梯停止了...");
}
}
1.6、状态应用对象/环境
public class Context {
/**
* 定义出所有的电梯状态
*/
public final static OpenningState openningState = new OpenningState();
public final static ClosingState closeingState = new ClosingState();
public final static RunningState runningState = new RunningState();
public final static StoppingState stoppingState = new StoppingState();
/**
* 定一个当前电梯状态
*/
private LiftState liftState;
public LiftState getLiftState() {
return liftState;
}
/**
* 将状态和环境绑定
*/
public void setLiftState(LiftState liftState) {
this.liftState = liftState;
this.liftState.setContext(this);
}
public void open() {
this.liftState.open();
}
public void close() {
this.liftState.close();
}
public void run() {
this.liftState.run();
}
public void stop() {
this.liftState.stop();
}
}
1.7、测试
public class Z19Main {
public static void main(String[] args) {
Context context = new Context();
context.setLiftState(new ClosingState());
context.open();
System.out.println("--------");
context.close();
System.out.println("--------");
context.run();
System.out.println("--------");
context.stop();
}
}
3、总结
状态模式,对我个人来说是没怎么用过的,因为在场景中我所使用的状态,都是直接从一个状态到另一个状态,直接修改的。其实仔细想想,也可以使用状态模式,比如现在小米这个里面有个产品的状态(关闭,开启,合同待配置,废弃),我们当我们关闭的时候,如果开启,需要判断合同需要配置,然后才能开启,如果合同配置则让他到合同待配置状态,
总之,以后遇到一些关于状态比较多(对象的行为取决于它的状态),修改起来需要判断当前状态并且,是否可以过度到另一个状态的时候,可以使用 。
感兴趣的,欢迎添加博主微信
哈,博主很乐意和各路好友交流,如果满意,请打赏博主任意金额,感兴趣的在微信转账的时候,备注您的微信或者其他联系方式。添加博主微信哦。
请下方留言吧。可与博主自由讨论哦
微信 | 微信公众号 | 支付宝 |
---|---|---|