详解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你的验证码安全码?
Jan 02 PHP
PHP 判断常量,变量和函数是否存在
Apr 26 PHP
PHP 事务处理数据实现代码
May 13 PHP
php 变量未定义等错误的解决方法
Jan 12 PHP
php数组函数序列之array_unshift() 在数组开头插入一个或多个元素
Nov 07 PHP
解决PHP mysql_query执行超时(Fatal error: Maximum execution time …)
Jul 03 PHP
回帖脱衣服的图片实现代码
Feb 15 PHP
PHP版QQ互联OAuth示例代码分享
Jul 05 PHP
ThinkPHP安装和设置
Jul 27 PHP
CodeIgniter配置之routes.php用法实例分析
Jan 19 PHP
php HTML无刷新提交表单
Apr 05 PHP
php连接mysql数据库最简单的实现方法
Sep 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 addslashes()与addclashes()函数的区别和比较
2013/06/24 PHP
php实现比较两个字符串日期大小的方法
2015/05/12 PHP
Prototype使用指南之dom.js
2007/01/10 Javascript
用jQuery扩展自写的 UI导航
2010/01/13 Javascript
基于jquery的高性能td和input切换并可修改内容实现代码
2011/01/09 Javascript
js实现的跟随鼠标移动的时钟效果(中英文日期显示)
2011/01/17 Javascript
JavaScript中this的使用详解
2013/11/08 Javascript
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
轻松创建nodejs服务器(10):处理上传图片
2014/12/18 NodeJs
javascript实现瀑布流自适应遇到的问题及解决方案
2015/01/28 Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
2016/02/26 Javascript
Javascript 获取鼠标当前的位置实现方法
2016/10/27 Javascript
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
vue项目打包部署到服务器的方法示例
2018/08/27 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
2020/05/14 Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
2020/06/01 Javascript
微信小程序实现发微博功能的示例代码
2020/06/24 Javascript
Django 连接sql server数据库的方法
2018/06/30 Python
对Python的zip函数妙用,旋转矩阵详解
2018/12/13 Python
简单易懂Pytorch实战实例VGG深度网络
2019/08/27 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
2020/02/07 Python
在tensorflow中设置使用某一块GPU、多GPU、CPU的操作
2020/02/07 Python
详解PyQt5信号与槽的几种高级玩法
2020/03/24 Python
DataFrame.groupby()所见的各种用法详解
2020/06/14 Python
python可视化分析的实现(matplotlib、seaborn、ggplot2)
2021/02/03 Python
美国真皮手袋品牌:GiGi New York
2017/03/10 全球购物
锐步美国官方网站:Reebok美国
2018/01/10 全球购物
精选鞋类、服装和配饰的全球领先目的地:Bodega
2021/02/27 全球购物
初中生三年学习生活的自我评价
2013/11/03 职场文书
公司庆典活动邀请函
2014/01/09 职场文书
高二政治教学反思
2014/02/01 职场文书
英语教师求职信
2014/06/16 职场文书
简历自荐信范文
2015/03/09 职场文书
《王国之心》迎来了发售的20周年, 野村哲发布贺图
2022/04/11 其他游戏
《火纹风花雪月无双》预告“神秘雇佣兵” 紫发剑客
2022/04/13 其他游戏