详解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&amp;mysql(一)
Oct 09 PHP
PHP 执行系统外部命令 system() exec() passthru()
Aug 11 PHP
PHP 存储文本换行实现方法
Jan 05 PHP
php中将数组存到文件里的实现代码
Jan 19 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(二)
Jun 23 PHP
ThinkPHP分组下自定义标签库实例
Nov 01 PHP
Yii开启片段缓存的方法
Mar 28 PHP
PHP flush 函数使用注意事项
Aug 26 PHP
php 微信公众平台开发模式实现多客服的实例代码
Nov 07 PHP
为何说PHP引用是个坑,要慎用
Apr 02 PHP
PHP格式化显示时间date()函数代码
Oct 03 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
Sep 27 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发电子邮件
2006/10/09 PHP
Windows中安装Apache2和PHP4权威指南
2006/11/18 PHP
Ajax+PHP 边学边练之四 表单
2009/11/27 PHP
php使用fopen创建utf8编码文件的方法
2014/10/31 PHP
yii2实现根据时间搜索的方法
2016/05/25 PHP
js利用事件的阻止冒泡实现点击空白模态框的隐藏
2014/01/24 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
js实现简单的可切换选项卡效果
2015/04/10 Javascript
nodejs爬虫抓取数据乱码问题总结
2015/07/03 NodeJs
location.hash保存页面状态的技巧
2016/04/28 Javascript
详解nodejs 文本操作模块-fs模块(四)
2016/12/22 NodeJs
基于JS实现网页中的选项卡(两种方法)
2017/06/16 Javascript
vue中使用localstorage来存储页面信息
2017/11/04 Javascript
vue计算属性时v-for处理数组时遇到的一个bug问题
2018/01/21 Javascript
webpack源码之loader机制详解
2018/04/06 Javascript
vue项目首屏加载时间优化实战
2019/04/23 Javascript
微信小程序日历弹窗选择器代码实例
2019/05/09 Javascript
[56:35]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第一局
2016/03/06 DOTA
详细解读Python中解析XML数据的方法
2015/10/15 Python
Python自动化运维和部署项目工具Fabric使用实例
2016/09/18 Python
利用Opencv中Houghline方法实现直线检测
2018/02/11 Python
Python subprocess模块功能与常见用法实例详解
2018/06/28 Python
[原创]Python入门教程1. 基本运算【四则运算、变量、math模块等】
2018/10/28 Python
Python numpy.array()生成相同元素数组的示例
2018/11/12 Python
解决Jupyter notebook更换主题工具栏被隐藏及添加目录生成插件问题
2020/04/20 Python
基于python实现matlab filter函数过程详解
2020/06/08 Python
如何基于Python爬取隐秘的角落评论
2020/07/02 Python
纯CSS3+DIV实现小三角形边框效果的示例代码
2020/08/03 HTML / CSS
Supersmart英国:欧洲市场首批食品补充剂供应商之一
2018/05/05 全球购物
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
巴西网上药店:Drogaria Araujo
2021/01/06 全球购物
计算机专业个人求职自荐信
2013/09/21 职场文书
毕业晚会主持词
2014/03/24 职场文书
超市收银员岗位职责
2015/04/07 职场文书
党员干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
MySQL不使用order by实现排名的三种思路总结
2021/06/02 MySQL