首页 > 经验记录 > Pattern > 设计模式(java实现)_状态模式(State)

设计模式(java实现)_状态模式(State)

我总感觉网上写的和我写的不是同一个模式似的…

我这个状态切换的流畅的一批,而且外部调用者完全与其状态的变换隔离。

也完美符合迪米特法则,新增状态原有代码逻辑一丝都不用修改。

就是实现起来略复杂

 

核心:

  • 用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题

 

结构:

-Context环境类

  • 环境类中维护一个State对象,他是定义了当前的状态

-State抽象状态类

-ConcreteState具体状态类

  • 每一个类封装了该状态对应的行为

 

简单点说:

状态模式封装的非常好,状态的变更引起了行为的变更,状态变换放置到了类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变换,从外部看起来就好像这个对象对应的类发生了改变一样。

 

下面是我写的代码,用酒店的房间作为例子。

其房间有三种状态,1:空闲、2:预定、3:已入住,我将以这三种状态的变换来演示状态模式的奥妙

 

State 接口

 

 

Context环境类:

 

说明:

到这就需要说明一下。这个状态和环境是一个你中有我,我中有你的结构。可以看到他们都有一个 Set方法 ,这个方法就是用于动态的变换。会经常用到。

状态中有环境,是因为状态变更时需要操作环境,将环境所维护的状态改变。状态变更时如何操作环境?你将在下面几个子类中看到

环境中有状态,环境为何叫做环境?自然是代表状态所处的环境,客户端进行状态切换时,所面对的就是该环境对象。即调用方法依赖环境而不是状态。

 

3种房间的状态:

 

在状态变更时,会进行两步处理:

1、将环境类 Context 维护的状态改变为切换后的状态

2、触发该状态的方法

 

假设现在客户端拥有一个状态为【空闲】的环境,那么,在他调用环境的 booked() 方法时,会触发如下现象:

1、环境所维护的状态对象由【空闲】变为【预定】

2、预定对象的  booked() 方法被调用,打印出”已预订”。

此时环境已经为预定状态。

 

下面看我使用一个客户端演示切换状态:

 

System.out:

已预订
退房,行吧
空闲状态~
没预定你住你马呢?
已预订
已入住
退房,行吧
空闲状态~

 

看看,是不是这个客户端只用管切换状态就对了,其余的都与其无关?

观察我写的代码,可以发现状态模式可扩展性极强,若想新增一个状态,源代码逻辑一点都不需要变动。只需要在新增一个状态类并且在接口和环境中新增对应的方法和属性即可。真正的对修改关闭对扩展开放。

 

这个模式实现起来还是比较抽象的。若是想在实际项目中将其优势完美发挥,估计得需要一点编码内力才行。我也不确定我能否将其完美运用。估计机会也不多。

不过,状态模式确实使我有种:原来代码还能这么玩? 的感觉,真的是太灵性了。

 

 

           


EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00