详解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程序的方法
Mar 09 PHP
php与php MySQL 之间的关系
Jul 17 PHP
使用php判断服务器是否支持Gzip压缩功能
Sep 24 PHP
php自动识别文件编码并转换为UTF-8的方法
Jun 12 PHP
用 Composer构建自己的 PHP 框架之使用 ORM
Oct 30 PHP
php模拟用户自动在qq空间发表文章的方法
Jan 07 PHP
php在apache环境下实现gzip配置方法
Apr 02 PHP
PHP list() 将数组中的值赋给变量的简单实例
Jun 13 PHP
php基于闭包实现函数的自调用(递归)实例分析
Nov 11 PHP
php对xml文件的增删改查操作实现方法分析
May 19 PHP
完美的php分页类
Oct 24 PHP
laravel5实现微信第三方登录功能
Dec 06 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绘图之生成饼状图的方法
2015/01/24 PHP
js 操作符实例代码
2009/10/24 Javascript
js 键盘记录实现(兼容FireFox和IE)
2010/02/07 Javascript
ext 列表页面关于多行查询的办法
2010/03/25 Javascript
jQuery学习笔记之Helloworld
2010/12/22 Javascript
javaScript 利用闭包模拟对象的私有属性
2011/12/29 Javascript
javascript常用对话框小集
2013/09/13 Javascript
Nodejs学习笔记之Stream模块
2015/01/13 NodeJs
js实现鼠标触发图片抖动效果的方法
2015/02/27 Javascript
JS实现的图片预览插件与用法示例【不上传图片】
2016/11/25 Javascript
js遍历json对象所有key及根据动态key获取值的方法(必看)
2017/03/09 Javascript
node.js中debug模块的简单介绍与使用
2017/04/25 Javascript
AngularJS实现select的ng-options功能示例
2017/07/12 Javascript
javascript 面向对象实战思想分享
2017/09/07 Javascript
浅谈AngularJS中使用$resource(已更新)
2017/09/14 Javascript
微信、QQ、微博、Safari中使用js唤起App
2018/01/24 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
微信小程序开发常见问题及解决方案
2019/07/11 Javascript
element-ui 远程搜索组件el-select在项目中组件化的实现代码
2019/12/04 Javascript
Vue单文件组件开发实现过程详解
2020/07/30 Javascript
[01:29:17]RNG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
跟老齐学Python之关于循环的小伎俩
2014/10/02 Python
Python抓取百度查询结果的方法
2015/07/08 Python
python深度优先搜索和广度优先搜索
2018/02/07 Python
python os模块在系统管理中的应用
2020/06/22 Python
Python自定义sorted排序实现方法详解
2020/09/18 Python
python Matplotlib数据可视化(1):简单入门
2020/09/30 Python
python collections模块的使用
2020/10/16 Python
使用HTML5的Notification API制作web通知的教程
2015/05/08 HTML / CSS
HTML table 表格边框的实现思路
2019/10/12 HTML / CSS
.NET remoting的两种通道是什么
2016/05/31 面试题
宣传部部长竞选演讲稿
2014/04/26 职场文书
教师学习三严三实心得体会
2014/10/13 职场文书
2016应届毕业生实习心得体会
2015/10/09 职场文书
Nginx使用X-Accel-Redirect实现静态文件下载的统计、鉴权、防盗链、限速等
2021/04/04 Servers
Python打包exe时各种异常处理方案总结
2021/05/18 Python