透过源码学习设计模式5 您所在的位置:网站首页 springboot状态机封装 透过源码学习设计模式5

透过源码学习设计模式5

#透过源码学习设计模式5| 来源: 网络整理| 查看: 265

简介:

状态模式即允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类,换句话说状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。

角色:

(1)、Context:上下文,定义客户端可能调用的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。

(2)、State:定义一个接口,用以封装环境对象的一个特定的状态所对应的行为。

(3)、ConcreteState:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

例子:

before :

class ElectricFanControl { private int currentState; public ElectricFanControl() { currentState = 0; } public void pull() { if (currentState == 0) { currentState = 1; System.out.println("low speed"); } else if (currentState == 1) { currentState = 2; System.out.println("medium speed"); } else if (currentState == 2) { currentState = 3; System.out.println("high speed"); } else { currentState = 0; System.out.println("turning off"); } } } public class StateDemo { public static void main(String[] args) { ElectricFanControl electricFanControl = new ElectricFanControl(); while (true) { System.out.print("Press ENTER"); getLine(); electricFanControl.pull(); } } static String getLine() { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String line = null; try { line = in.readLine(); } catch (IOException ex) { ex.printStackTrace(); } return line; } }

after:

//State接口: public interface State { public void start(Context context); public void close(Context context); } //StartState 类: class StartState implements State { @Override public void start(Context context) { System.out.println("do noting"); } @Override public void close(Context context) { System.out.println("close State"); context.setState(new CloseState()); } } class CloseState implements State { @Override public void start(Context context) { System.out.println("start State"); context.setState(new StartState()); } @Override public void close(Context context) { System.out.println("do noting"); } } class Context { private State state; public void setState(State state) { this.state = state; } public State getState() { return state; } public void start() { getState().start(this); } public void close() { getState().close(this); } } public class StatePatternDemo { public static void main(String... args) { Context context = new Context(); // 初始为开始状态 context.setState(new StartState()); // 切换为关闭状态 context.close(); // 切换为开始状态 context.start(); } } 一般使用场景:

控制对象状态转换的条件逻辑过于复杂,用处理特殊状态和状态转换的state类替换条件语句

优缺点:

优点:

简化复杂的状态改变逻辑,有利于代码的阅读、维护和扩展。

缺点:

状态类增加,设计复杂度提高

Spring State Machine示例:

状态机(状态模式的一种应用)在工作流或游戏等各种系统中有大量使用,如各种工作流引擎,它几乎是状态机的子集和实现,封装状态的变化规则。Spring状态机帮助开发者简化状态机的开发过程,让状态机结构更加层次化。

如下代码显示如何用Spring状态机来实现一个洗衣机的工作流程:

定义状态和事件枚举类:

public enum States { RUNNING, HISTORY, END, WASHING, RINSING, DRYING, POWEROFF } public enum Events { RINSE, DRY, STOP, RESTOREPOWER, CUTPOWER }

状态机配置:状态

通过多次调用withStates() 定义分层state, 你可以使用parent() 指定这些特定state是其他state的子state。

@Override public void configure(StateMachineStateConfigurer states) throws Exception { states .withStates() .initial(States.RUNNING) .state(States.POWEROFF) .end(States.END) .and() .withStates() .parent(States.RUNNING) .initial(States.WASHING) .state(States.RINSING) .state(States.DRYING) .history(States.HISTORY, History.SHALLOW); }

状态机配置:状态转化

三种不同类型的转换:外部转换、内部转换和本地转换。转换要么由信号(发送到状态机的事件)触发,要么由计时器触发

@Override public void configure(StateMachineTransitionConfigurer transitions) throws Exception { transitions .withExternal() .source(States.WASHING).target(States.RINSING) .event(Events.RINSE) .and() .withExternal() .source(States.RINSING).target(States.DRYING) .event(Events.DRY) .and() .withExternal() .source(States.RUNNING).target(States.POWEROFF) .event(Events.CUTPOWER) .and() .withExternal() .source(States.POWEROFF).target(States.HISTORY) .event(Events.RESTOREPOWER) .and() .withExternal() .source(States.RUNNING).target(States.END) .event(Events.STOP); }

后续:与策略模式的比较

同:

1、子类的使用:状态和策略模式都通过状态/策略的不同派生子类来更改具体实现。

2、模式类图:状态模式和策略模式之间最大的相似性之一是它们的类图,除了类名之外,它们看起来几乎相同。这两种模式都定义了状态/策略基类,子状态/子策略都继承基类。

3、两者都遵循开闭原则:状态模式的Context是对修改关闭的,即关于状态如何被访问和使用的逻辑是固定的。但是各个状态是开放的,也就是说,可以通过扩展可以添加更多的状态。类似地,策略模式的context是对修改关闭的,但是各个策略的子类是开放可扩展的。

异:

1、模式意图:策略模式的意图或目的是拥有一系列可互换的算法,这些算法可以根据context和/或客户需求进行选择。而状态模式的目的是管理对象的状态以及对象的行为,对象的行为会随着状态的变化而变化。

2、客户端对策略/状态的感知:在策略模式实现中,所选择的策略依赖于客户端,因此客户端知道使用的是哪种策略。而在状态模式实现中,客户端与context交互以对对象进行操作,但不决定选择哪种状态。对象本身似乎根据客户端通过context进行的交互来更改其状态类。

3、context的引用:状态模式中的每个状态都持有context的引用。但是,策略模式中每个策略并不持有context的引用。

4、状态/策略之间的关系:状态模式中的不同状态彼此相关,例如作为前一个或者后一个状态等。这是因为在状态之间像有限状态机有一个流动。然而,策略模式只是从多个可用策略中选择一个策略,策略之间没有后者/前者的关系。

5、怎样做/什么&何时做:多种策略定义了做某事的多种方式。而多个状态定义要做什么,并基于状态之间的关系定义何时做。

java达人

ID:drjava

(长按或扫码识别)



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有