Design Patterns(二十一):State Pattern--VB代码

结构图

 

角色

  • 环境(Subject)角色:负责定义客户感兴趣的接口,并维护一个具体状态(ConcreteState)的实例,以及维护状态转换或为这种转换提供支持(因为状态转换有时候可能是由上层应用发起的)。
  • 状态(State)角色:定义一个接口以封装与环境(Context)角色的一个特定状态相关的行为。
  • 具体状态(ConcreteState)角色:)每一个子类实现一个与环境(Context)角色状态相关的行为。

动机

  在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
     如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?

意图

  
允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。

示意性代码

示意性代码

 

 一个实例

    下面的状态模式代码演示了一个帐户在处于不同状态时可以进行不同的操作。在行为上的区别委派给以下三个对象红色状态(RedState),灰色状态(SilverState),金色状态(GoldState)。这些状态分别代表透支帐户,新开通的帐户,和拥有良好信誉的帐户。

旧系统代码

在开发中时常遇到的根据不同的状态需要进行不同的处理操作的问题,而这样的问题,大部分人是采用Select-Case/If-Else语句进行处理的,这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对原来的代码进行编译.State模式采用了对这些不同的状态进行封装的方式处理这类问题,当状态改变的时候进行处理然后再切换到另一种状态,也就是说把状态的切换责任交给了具体的状态类去负责.具体的状态类可以通过派生的方式不依赖于其他对象而独立变化。

运用模式后的代码

 

State Pattern模式的几个要点:
   1、State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
   2、为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的——即要么彻底转换过来,要么不转换。
     3、如果State对象没有实例变量,那么各个上下文可以共享一个State对象,从而节省对象开销。

我的理解

封装与状态相关的行为,支持状态的变化。

参考资料
《C#面向对象设计模式纵横谈系列课程(21)》     李建中老师