<>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开门 行为关门 行为运行 行为停止 行为
开门 态noyesnono
关门 态yesnoyesyes
运行 态nononoyes
停止 态yesnoyesno
<>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
LiftStategetOpenningState() { 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(); }
<>运行结果
执行开门动作 执行关门动作 电梯上下运行中... 电梯停止运行...
<>参考:

《设计模式之禅》

<>========== THE END ==========

技术
©2020 ioDraw All rights reserved
Vue2.0+jsonserver+axios模拟本地请求接口数据django不关闭CSRF中间件,自定义通过CSRF检测的post请求网上赚钱的门路方法,大部分人都是利用这三种方法!JS基础重点知识实验总结(全)HashMap实现LRU(最近最少使用)缓存更新算法特征工程vue el-input 禁止输入特殊字符 只可输入数字 正则验证抖音比较火的 黑客帝国-代码雨(免费送)携程2019校招 LRU Cachek8s删除pod