首页 > 代码库 > 状态模式的应用

状态模式的应用

前景:

     xx公司要启动一个项目,这个项目的需求是合同协议管理,需求分别为:

      1.  合作的过程中创建一份协议。

      2.  协议开始的过程中可以暂停和恢复。

      3.  当然合作可以延长合作时间和提前结束,不管哪一种都要算服务天数,因为费用是按天计算的。

      4.  财务可以看到本月实际的营业额。

    接到需求之后就有人开始编码了(这是国内的习惯):

     协议创建的时候的合法性检测:

#检测是否存在合作中的协议.....$isCooperation = Agreement::model()->exists("nick=? and begin_date>=? and end_date<=?",array(‘xx‘,date(),date()));if($isCooperation){     throw new Exception("存在合作中的协议,无法新建");    }#检测是否有暂停的协议$isExistsStop =  Agreement::model()->exists("nick=? and status=?",array(‘xx‘,‘stop‘));if($isExistsStop){      throw new Exception("存在暂停的协议,无法新建");    }......

  协议开始的时候的合法性检测:

#检测是否存在为开始状态的协议$agreement = Agreement::model()->find("nick=? and status=? begin_date>=? and end_date<=?",array(‘xx‘,‘NotStart‘,date(),date()));if($agreement == null){     throw new Exception("未找到开始状态的订单");}$agreement->start_date = date();$agreement->status = ‘Start‘;$agreement->save(); ......

  协议暂停的时候的合法性检测:

同上,状态越来越多 的时候,我们就越来越麻木了,不知道当前的动作会转变成什么状态,前置状态是否合理。

解决这一问题,我们引进下设计模式这个概念,其实代码基础还是不会变,只是转成了另外一种表现形式。

分析下我们从需求中提出动词:

1. 开始 (Start)

2. 暂停 (Pause)

3. 恢复 (Resume)

4. 终止 (Over)

5. 续约 (Review)

根据状态,我们列出以下状态:

1. 未开始(NotStart)

2. 服务中 (Start)

3. 暂停服务 (Pause)

4. 服务结束 (Over)

 

我们在来列一份表格

   未开始    服务中    暂停服务    服务结束  
  开始    服务中  error  error    error
  暂停  error  暂停服务  error  error
  恢复  error  error  服务中  error
  终止     服务结束  服务结束  服务结束  服务结束
  续约  未开始  服务中  error  未开始/服务中  

这份表格代表着状态的转化过程。

 

状态模式解读:http://www.cnblogs.com/wangjq/archive/2012/07/16/2593485.html

1. 概述

  当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

2. 解决的问题

  主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单化。

3. 模式中的角色

  3.1 上下文环境(Context):它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的Concrete State对象来处理。

  3.2 抽象状态(State):定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。

  3.3 具体状态(Concrete State):实现抽象状态定义的接口。