详解PHP中的状态模式编程


Posted in PHP onAugust 11, 2015

定义
状态模式,又称状态对象模式(Pattern of Objects for State),状态模式就是对象的行为模式。状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样

UML图

详解PHP中的状态模式编程

状态模式中主要角色
抽象状态角色(State):定义一个接口或抽象类State,用以封装环境对象的一个特定的状态所对应的行为
具体状态(ConcreteState)角色:每一个状态类都实现了环境(Context)的一个状态所对应的行为
环境(Context)角色:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态


使用场景
考虑一个在线投票系统的应用,要实现控制同一用户只能投一票,如果一个用户反复投票,而且投票超过5次,则判定为恶意刷票,如果投票超过8次,需要加入黑名单

要使用状态模式实现,首先要把投票过程的各种状态定义出来,根据以上描述大致分为四种状态:正常投票,恶意投票,黑名单投票。然后创建一个投票管理对象(相当于Context)

UML图

详解PHP中的状态模式编程

示例代码

 

<?php 
  
 /** 
  * 抽象状态类 
  * @author wzy 
  * 
  */ 
 interface VoteState 
 { 
  
  /** 
   * 需要实现的公共方法 
   */ 
  public function vote (); 
 } 
  
 /** 
  * 具体状态——正常投票 
  * 
  * @author wzy 
  *   
  */ 
 class NormalVoteState implements VoteState 
 { 
  
  public function vote () 
  { 
   echo "这是一个正常投票!"; 
  } 
 } 
  
 /** 
  * 具体状态——恶意投票 
  * 
  * @author wzy 
  *   
  */ 
 class RepeatVoteState implements VoteState 
 { 
  
  public function vote () 
  { 
   echo "这是一个恶意投票!"; 
  } 
 } 
  
 /** 
  * 具体状态——黑名单投票 
  * 
  * @author wzy 
  *   
  */ 
 class BlockVoteState implements VoteState 
 { 
  
  public function vote () 
  { 
   echo "这是一个黑名单投票!"; 
  } 
 } 
  
 /** 
  * Context角色 
  */ 
 class VoteManager 
 { 
  
  /** 
   * 投票数量 
   * 
   * @var int 
   */ 
  private $vote_count; 
  
  /** 
   * 状态类实例 
   * 
   * @var object 
   */ 
  private $voteInstance; 
  
  /** 
   * 构造函数,初始化成员属性 
   * 
   * @param int $count    
   */ 
  public function __construct ($count = 1) 
  { 
   $this->vote_count = $count; 
  } 
  
  /** 
   * 客户端调用的接口函数 
   */ 
  public function setState ($count) 
  { 
   if (! is_null($count)) { 
    $this->vote_count = $count; 
   } 
   if ($this->vote_count < 5) { 
    $this->voteInstance = new NormalVoteState(); 
   } else 
    if ($this->vote_count < 8) { 
     $this->voteInstance = new RepeatVoteState(); 
    } else { 
     $this->voteInstance = new BlockVoteState(); 
    } 
    
   $this->voteInstance->vote(); 
  } 
 } 
  
 /** 
  * 模拟客户端操作 
  */ 
  
 $object = new VoteManager(); 
 $object->setState(1); 
 echo "<br>"; 
 $object->setState(6); 
 echo "<br>"; 
 $object->setState(10);

回顾状态模式
状态和行为
所谓对象的状态,通常指的就是对象实例的属性的值;而行为指的就是对象的功能,在具体一点说,行为大多可以对应到方法上

状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的功能。也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为

由于状态是在运行期被改变的,因为行为也会在运行期根据状态的改变而改变

环境和状态处理对象
在状态模式中,环境(Context)是持有状态的对象,但是环境自己并不处理跟状态相关的行为,而是把处理状态的功能委托给了状态对应的状态处理类来处理

在具体的状态处理中经常需要获取环境(Context)自身的数据,可以考虑用抽象类替代接口,这样可能会更方便参数的传递

客户端一般只与环境(Context)交互。客户端可以用状态对象来配置一个环境(Context),一旦配置完毕,就不再需要和状态对象打交道了。客户端通常不负责运行期间的状态维护,也不负责后续到底使用哪一个具体的状态处理对象

PHP 相关文章推荐
php 获取mysql数据库信息代码
Mar 12 PHP
PHP 实用代码收集
Jan 22 PHP
PHP下escape解码函数的实现方法
Aug 08 PHP
php下统计用户在线时间的一种尝试
Aug 26 PHP
linux下为php添加curl扩展的方法
Jul 29 PHP
php输出echo、print、print_r、printf、sprintf、var_dump的区别比较
Jun 21 PHP
PHP三元运算的2种写法代码实例
May 12 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十)
Jun 24 PHP
PHP获取时间排除周六、周日的两个方法
Jun 30 PHP
PHP常用技巧汇总
Mar 04 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
Sep 16 PHP
PHP二维索引数组的遍历实例分析【2种方式】
Jun 24 PHP
简单介绍PHP的责任链编程模式
Aug 11 #PHP
PHP会话处理的10个函数
Aug 11 #PHP
PHP的Socket网络编程入门指引
Aug 11 #PHP
php实现的农历算法实例
Aug 11 #PHP
PHP发送短信代码分享
Aug 11 #PHP
php实现可逆加密的方法
Aug 11 #PHP
PHP实现获取某个月份周次信息的方法
Aug 11 #PHP
You might like
具有时效性的php加密解密函数代码
2013/06/19 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
JavaScript中的ubound函数使用实例
2014/11/04 Javascript
简单谈谈javascript代码复用模式
2015/01/28 Javascript
JS运动基础框架实例分析
2015/03/03 Javascript
JS使用单链表统计英语单词出现次数
2016/06/16 Javascript
jQuery Ajax 异步加载显示等待效果代码分享
2016/08/01 Javascript
js使用Replace结合正则替换重复出现的字符串功能示例
2016/12/27 Javascript
微信小程序图片横向左右滑动案例
2017/05/19 Javascript
js 获取元素的具体样式信息getcss(实例讲解)
2017/07/05 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
clipboard.js在移动端复制失败的解决方法
2018/06/13 Javascript
JS实现动态生成html table表格的方法分析
2018/07/11 Javascript
中高级前端必须了解的JS中的内存管理(推荐)
2019/07/04 Javascript
[00:58]他们到底在电话里听到了什么?
2017/11/21 DOTA
Python ljust rjust center输出
2008/09/06 Python
Python爬虫通过替换http request header来欺骗浏览器实现登录功能
2018/01/07 Python
python中验证码连通域分割的方法详解
2018/06/04 Python
用Python中的turtle模块画图两只小羊方法
2019/04/09 Python
HTML5的结构和语义(3):语义性的块级元素
2008/10/17 HTML / CSS
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
2012/06/04 HTML / CSS
canvas环形倒计时组件的示例代码
2018/06/14 HTML / CSS
关于html字符串正则判断和匹配的具体使用
2019/12/12 HTML / CSS
科尔士百货公司官网:Kohl’s
2016/07/11 全球购物
SkinCeuticals官网:美国药妆品牌
2018/04/19 全球购物
台湾全方位线上课程与职能学习平台:TibaMe
2019/12/04 全球购物
牵手50新加坡:专为黄金岁月的单身人士而设的交友网站
2020/08/16 全球购物
Linux如何压缩可执行文件
2013/10/21 面试题
市优秀教师事迹材料
2014/02/05 职场文书
冬季安全检查方案
2014/05/23 职场文书
农行心得体会
2014/09/02 职场文书
护士长2014年度工作总结
2014/11/11 职场文书
2015年部门工作总结范文
2015/03/31 职场文书
党支部评议意见
2015/06/02 职场文书
MySQL 分页查询的优化技巧
2021/05/12 MySQL
Java使用httpRequest+Jsoup爬取红蓝球号码
2021/07/02 Java/Android