Java 有限状态机 (设计模式——状态模式)

编写代码的时候,有时会遇见较为复杂的swith...case...和if...else...语句。这一刻有时会想到状态机,用有限状态机替换swith...case...和if...else...可以:

降低程序的复杂度;

提高程序的可维护性;

状态机模式体现了开闭原则和单一职责原则。

每个状态都是一个子类,增加状态就要增加子类;修改状态只要修改一个类就行了。

以上是有限状态机的好处。其亦有缺点:

使用状态机子类会增多,也就是类膨胀,这点需要程序员在开发中自己衡量。

状态模式定义:

Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.

允许对象在其内部状态发生变化时更改其行为。看起来像更改了其类 (这翻译不好,这里应该是体现了其封装性:外部的调用不用知道其内部如何实现状态和行为变化的)。

举个例子

我们每天都乘坐电梯,电梯有四种状态:开门、关门、运行、停止。

Col1

开门 行为

关门 行为

运行 行为

停止 行为

开门 态

no

yes

no

no

关门 态

yes

no

yes

yes

运行 态

no

no

no

yes

停止 态

yes

no

yes

no

LiftState.java

/**

* 定义电梯行为:打开、关闭、运行、停止

*/

public abstract class LiftState {

// 拥有一个电梯对象,用于更新电梯当前状态

protected Lift mLift;

/**

* 通过构造函数引入电梯的实例化对象

*

* @param lift

*/

public LiftState(Lift lift) {

this.mLift = lift;

}

/**

* 行为:打开电梯门

*/

public abstract void open();

/**

* 行为:关闭电梯门

*/

public abstract void close();

/**

* 行为:电梯运行

*/

public abstract void run();

/**

* 行为:电梯停止运行

*/

public abstract void stop();

}

电梯的四种状态

public class OpeningState extends LiftState {

public OpeningState(Lift lift) {

super(lift);

}

@Override

public void open() {

// 执行开门动作

System.out.println("执行开门动作");

}

@Override

public void close() {

// 执行关门动作

// 1、转化为关门状态

mLift.setState(mLift.getCloseingState());

// 2、关门

mLift.close();

}

@Override

public void run() {

// do noting

// 开门状态,不能执行运行动作

}

@Override

public void stop() {

// do noting

// 开门状态下,不执行停止动作

}

}

public class ClosingState extends LiftState {

public ClosingState(Lift lift) {

super(lift);

}

@Override

public void open() {

// 执行开门动作

// 1、变化为开门状态

this.mLift.setState(mLift.getOpenningState());

// 2、开门

this.mLift.open();

}

@Override

public void close() {

System.out.println("执行关门动作");

}

@Override

public void run() {

// 运行动作

// 1、运行状态

this.mLift.setState(mLift.getRunningState());

// 2、运行动作

this.mLift.run();

}

@Override

public void stop() {

// 停止动作

// 1、转化为停止状态

this.mLift.setState(mLift.getStoppingState());

// 2、停止

this.mLift.stop();

}

}

public class RunningState extends LiftState {

public RunningState(Lift lift) {

super(lift);

}

@Override

public void open() {

// do noting

}

@Override

public void close() {

// do noting

}

@Override

public void run() {

// 运行动作

System.out.println("电梯上下运行中...");

}

@Override

public void stop() {

// 停止动作

// 1、转化为停止状态

this.mLift.setState(mLift.getStoppingState());

// 2、停止动作

this.mLift.stop();

}

}

public class StoppingState extends LiftState {

public StoppingState(Lift lift) {

super(lift);

}

@Override

public void open() {

// 开门动作

// 1、开门状态

this.mLift.setState(mLift.getOpenningState());

// 2、执行开门动作

this.mLift.open();

}

@Override

public void close() {

// do noting

}

@Override

public void run() {

// 运行动作

// 1、运行状态

this.mLift.setState(mLift.getRunningState());

// 2、运行动作

this.mLift.run();

}

@Override

public void stop() {

// 电梯停止动作

System.out.println("电梯停止运行...");

}

}

定义电梯类

/**

* 定义电梯类

*/

public class Lift {

//定义出电梯的所有状态

private LiftState openningState;

private LiftState closingState;

private LiftState runningState;

private LiftState stoppingState;

// 定义当前电梯状态

private LiftState mCurState;

/**

* 构造方法

*/

public Lift() {

openningState = new OpeningState(this);

closingState = new ClosingState(this);

runningState = new RunningState(this);

stoppingState = new StoppingState(this);

}

/**

* 执行开门动作

*/

public void open() {

mCurState.open();

}

/**

* 执行关门动作

*/

public void close() {

mCurState.close();

}

/**

* 执行运行动作

*/

public void run() {

mCurState.run();

}

/**

* 执行停止动作

*/

public void stop() {

mCurState.stop();

}

// ##################设置当前电梯状态#####################

/**

* 设置当前电梯状态

*

* @param state

*/

public void setState(LiftState state) {

this.mCurState = state;

}

// ###################获取电梯的全部状态####################

public LiftState getOpenningState() {

return openningState;

}

public LiftState getCloseingState() {

return closingState;

}

public LiftState getRunningState() {

return runningState;

}

public LiftState getStoppingState() {

return stoppingState;

}

}

运行

public static void main(String[] args) {

Lift lift = new Lift();

lift.setState(new ClosingState(lift));

lift.open();

lift.close();

lift.run();

lift.stop();

}

运行结果

执行开门动作

执行关门动作

电梯上下运行中...

电梯停止运行...

参考:

《设计模式之禅》

java中的状态机模式_Java 有限状态机 (设计模式——状态模式)相关推荐

  1. Java 有限状态机 (设计模式——状态模式)

    Java 有限状态机 (设计模式--状态模式) 编写代码的时候,有时会遇见较为复杂的swith...case...和if...else...语句.这一刻有时会想到状态机,用有限状态机替换swith.. ...

  2. Java 设计模式——状态模式

    概述 很多人在说状态模式的时候总拿策略模式来进行对比,可能他们的类图会有一点类似,可我却不认为他们有多么相像.你可以阅读<Java设计模式--策略模式>这篇博客,并与本文对比,以找到蛛丝马 ...

  3. Java设计模式——状态模式【State Pattern】

    一.引言 23种设计模式大概分为三大类: 5种(创建型模式):工厂方法模式.抽象工厂模式.单例模式.原型模式.建造者模式. 7种(结构型模式):适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组 ...

  4. java设计模式---状态模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...

  5. JAVA 设计模式 : 状态模式

    原文出处: 屌丝码农 一.引出状态模式 假设我们现在有一个糖果机项目,那么我们知道正常一般糖果机提供给用户的行为有这么几种:投入硬币.转动曲柄.退出硬币几种行为:那么糖果机呢一般有这几中状态,待机状态 ...

  6. Java设计模式—状态模式

    (尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_25827845/article/details/52468077冷血之心的博客) 目录 定义如下: 个人理解: 通用 ...

  7. Java多线程相关知识【17】--设计模式--上下文模式(Context)

    文章目录 Java多线程相关知识[17]--设计模式--上下文模式(Context) 1. 问题的引入 2. 解决方法 1. 解决理论 2. 实操代码 上下文数据保存 上文 下文 调度者 测试上下文 ...

  8. 深入理解Java设计模式——状态模式

    目录 一.什么是状态模式 二.状态模式应用场景 三.状态模式实现 1. 需要重构的代码 四.状态模式与策略模式区别 五.状态模式实现 一.什么是状态模式 状态模式允许一个对象在其内部状态改变的时候改变 ...

  9. 设计模式-状态模式实现状态机

          1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的 ...

  10. 设计模式状态模式uml_UML的完整形式是什么?

    设计模式状态模式uml UML:统一建模语言 (UML: Unified Modeling Language) UML is an abbreviation of Unified Modeling L ...

最新文章

  1. 洛谷 P1636 Einstein学画画
  2. @Configurattion注解的作用及一些列组合使用
  3. node项目发送邮件失败
  4. 博弈论 斯坦福game theory stanford week 1.1
  5. C++学习笔记-----operator=函数处理自赋值
  6. CMake find_package
  7. linux下搭建FTP服务器
  8. python的lib文件夹_python遍历文件夹os.path与pathlib
  9. 启动kafka报错:__consumer_offsets-22\00000000000000000000.index.swap: 另一个程序正在使用此文件,进程无法访问。
  10. pandas拉长dataframe
  11. 首发天玑1200!Redmi电竞旗舰首曝:电池容量或超4500mAh
  12. R语言高级算法之人工神经网络(Artificial Neural Network)
  13. [设计模式之禅读书笔记]006_设计模式六大原则(六):开闭原则
  14. dnf服务器运行库,吃鸡需要什么运行库 | 手游网游页游攻略大全
  15. 【超级详细的Vue安装与配置教程】
  16. 迷你KMS mini-KMS_Activator_v1.3_Office2010_VL_ENG使用
  17. 程序员的办公好选择:工作效率翻倍,游戏也能超神
  18. 万字长文Python面试题,年后找工作就靠这了
  19. 微信JSSDK invalid signature签名错误的解决方法
  20. 联想电脑虚拟化开启方法

热门文章

  1. 23. Element lastChild 属性
  2. [洛谷P1501][国家集训队]Tree II(LCT)
  3. Django 学习第九天——请求与响应
  4. windows下的Redis安装:
  5. js------match() 方法
  6. 【转】和菜鸟一起学linux之DBUS基础学习记录
  7. mysql-查询一天,一周,一月,一年,以及mysql的基本日期函数
  8. mysqlbackup 还原特定的表
  9. SQL 数据库操作类
  10. 构造函数与一般函数的区别