详解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 相关文章推荐
一个简单实现多条件查询的例子
Oct 09 PHP
PHP 应用程序的安全 -- 不能违反的四条安全规则
Nov 26 PHP
PHP的curl实现get,post和cookie(实例介绍)
Jun 17 PHP
使用PHP函数scandir排除特定目录
Jun 12 PHP
修改ThinkPHP缓存为Memcache的方法
Jun 25 PHP
php cookie中点号(句号)自动转为下划线问题
Oct 21 PHP
PHP批量生成图片缩略图的方法
Jun 18 PHP
PHP结合Jquery和ajax实现瀑布流特效
Jan 07 PHP
Redis使用Eval多个键值自增的操作实例
Nov 04 PHP
详解PHP防止盗链防止迅雷下载的方法
Apr 26 PHP
php中Ioc(控制反转)和Di(依赖注入)
May 07 PHP
PHP number_format函数原理及实例解析
Jul 14 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+mysql留言本源码
2009/11/11 PHP
PHP调用Linux的命令行执行文件压缩命令
2013/01/27 PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
2014/03/08 PHP
ThinkPHP模板引擎之导入资源文件方法详解
2014/06/18 PHP
ThinkPHP行为扩展Behavior应用实例详解
2014/07/22 PHP
阿里云PHP SMS短信服务验证码发送方法
2017/07/11 PHP
Thinkphp5+uploadify实现的文件上传功能示例
2018/05/26 PHP
php获得刚插入数据的id 的几种方法总结
2018/05/31 PHP
详解如何实现Laravel的服务容器的方法示例
2019/04/15 PHP
使用Node.js实现一个简单的FastCGI服务器实例
2014/06/09 Javascript
jQuery超赞的评分插件(8款)
2015/08/20 Javascript
JS+CSS实现带有碰撞缓冲效果的竖向导航条代码
2015/09/15 Javascript
js获取iframe中的window对象的实现方法
2016/05/20 Javascript
jQuery unbind 删除绑定事件详解
2016/05/24 Javascript
jQuery实现简洁的轮播图效果实例
2016/09/07 Javascript
JS实现自动阅读单词(有道单词本添加功能)
2016/11/14 Javascript
Bootstrap CSS布局之列表
2016/12/15 Javascript
AngularJS开发教程之控制器之间的通信方法分析
2016/12/25 Javascript
基于jQuery实现数字滚动效果
2017/01/16 Javascript
angularjs定时任务的设置与清除示例
2017/06/02 Javascript
使用3D引擎threeJS实现星空粒子移动效果
2020/09/13 Javascript
Vue-cli3简单使用(图文步骤)
2019/04/30 Javascript
JAVA面试题 static关键字详解
2019/07/16 Javascript
JavaScript相等运算符的九条规则示例详解
2019/10/20 Javascript
[01:05:32]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第一局
2016/03/04 DOTA
Python实现发送email的几种常用方法
2014/08/18 Python
详解Django缓存处理中Vary头部的使用
2015/07/24 Python
PyQt5每天必学之切换按钮
2020/08/20 Python
python画图--输出指定像素点的颜色值方法
2019/07/03 Python
Python Numpy 控制台完全输出ndarray的实现
2020/02/19 Python
开学典礼决心书
2014/03/11 职场文书
求职信格式要求
2014/05/23 职场文书
火灾现场处置方案
2014/05/28 职场文书
党员年终个人总结
2015/02/14 职场文书
房屋维修申请报告
2015/05/18 职场文书
导游词之扬州大明寺
2019/10/09 职场文书