php设计模式 State (状态模式)


Posted in PHP onJune 26, 2011

状态state模式是GOF23种模式中的一种,和命令模式一样,也是一种行为模式。状态模式和命令模式相当像,一样是“接口—实现类”这种模式的应用,是面向接口编程原则的体现。

状态模式属于对象创建型模式,其意图是允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了他的类。比较常见的例子是在一个表示网络连接的类TCPConnection,一个TCPConnection对象的状态处于若干不同的状态之一:连接已经建立(Established),正在监听,连接已经关闭(closed)。当一个TCPConnection对象收到其他对象的请求时,他根据自身的状态作出不同的反应。

例如:一个Open请求的结果依赖于该连接已关闭还是连接已建立状态。State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。这一种模式的关键思想是引入了一个称为TCPState的抽象类表示网络的连接状态,TCPState类为各种表示不同的操作状态的字类声明了一个公共接口。TCPState的子类实现与特定的状态相关的行为。例如,TCPEstablished和TCPClosed类分别实现了特定于TCPConnection的连接已建立状态和连接已关闭状态的行为。

举例来说:一个人具有生气,高兴和抓狂等状态,在这些状态下做同一个事情可能会有不同的结果,一个人的心情可能在这三种状态中循环转变。使用一个moodState类表示一个人的心情,使用mad,Happy,Angry类代表不同的心情。

先看一个例子:

<?php 
/** 
* 状态模式 
* 
* 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它所属的类 
* 
*/ 
interface State 
{ 
public function handle($state); 
public function display(); 
} 
class Context 
{ 
private $_state = null; 
public function __construct($state) 
{ 
$this->setState($state); 
} 
public function setState($state) 
{ 
$this->_state = $state; 
} 
public function request() 
{ 
$this->_state->display(); 
$this->_state->handle($this); 
} 
} 
class StateA implements State 
{ 
public function handle($context) 
{ 
$context->setState(new StateB()); 
} 
public function display() 
{ 
echo "state A<br/>"; 
} 
} 
class StateB implements State 
{ 
public function handle($context) 
{ 
$context->setState(new StateC()); 
} 
public function display() 
{ 
echo "state B<br/>"; 
} 
} 
class StateC implements State 
{ 
public function handle($context) 
{ 
$context->setState(new StateA()); 
} 
public function display() 
{ 
echo "state C<br/>"; 
} 
} 
// 实例化一下 
$objContext = new Context(new StateB()); 
$objContext->request(); 
$objContext->request(); 
$objContext->request(); 
$objContext->request(); 
$objContext->request();

状态模式的理解,关键有2点:

1. 通常命令模式的接口中只有一个方法。 而状态模式的接口中有1个或者多个方法。而且,状态模式的实现类的方法,一般返回值;或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除if…else等条件选择语句。

2. 主要的用途是,作为实例变量,是一个对象引用。命令模式的主要的使用方式是参数回调模式。命令接口作为方法的参数传递进来。然后,在方法体内回调该接口。而状态模式的主要使用方法,是作为实例变量,通过set属性方法,或者构造器把状态接口的具体实现类的实例传递进来。因此,可以这样比较命令模式和状态模式的异同。

State模式和command模式都是十分常用,粒度比较小的模式,是很多更大型模式的一部分。基本上,state模式和command模式是十分相似的。只要开发者心中对单例和多例有一个清醒的认识,即使不把它们分为两种模式也没事。

PHP 相关文章推荐
用PHP控制用户的浏览器--ob*函数的使用说明
Mar 16 PHP
php使用递归函数实现数字累加的方法
Mar 16 PHP
PHP判断是否连接上网络的方法
Jul 01 PHP
php中preg_match的isU代表什么意思
Oct 01 PHP
对比PHP对MySQL的缓冲查询和无缓冲查询
Jul 01 PHP
PHP实现带重试功能的curl连接示例
Jul 28 PHP
golang 调用 php7详解及实例
Jan 04 PHP
PHP实现的数独求解问题示例
Apr 18 PHP
Yii2选项卡的简单使用
May 26 PHP
PHP实现基于状态的责任链审批模式详解
May 31 PHP
PHP的HTTP客户端Guzzle简单使用方法分析
Oct 30 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
Feb 21 PHP
php设计模式 Bridge (桥接模式)
Jun 26 #PHP
php设计模式 Chain Of Responsibility (职责链模式)
Jun 26 #PHP
php设计模式 FlyWeight (享元模式)
Jun 26 #PHP
php设计模式 Mediator (中介者模式)
Jun 26 #PHP
php设计模式 Prototype (原型模式)代码
Jun 26 #PHP
PHP如何解决网站大流量与高并发的问题
Jun 25 #PHP
session在PHP大型web应用中的使用
Jun 25 #PHP
You might like
坏狼php学习 计数器实例代码
2008/06/15 PHP
PHP 生成的XML以FLASH获取为乱码终极解决
2009/08/07 PHP
ThinkPHP自动验证失败的解决方法
2011/06/09 PHP
php两种无限分类方法实例
2015/04/21 PHP
用JavaScript获取网页中的js、css、Flash等文件
2006/12/20 Javascript
js实现图片放大缩小功能后进行复杂排序的方法
2012/11/08 Javascript
js 3种归并操作的实例代码
2013/10/30 Javascript
js正则表达式replace替换变量方法
2016/05/21 Javascript
浅谈JavaScript的内置对象和浏览器对象
2016/06/03 Javascript
node.js入门教程之querystring模块的使用方法
2017/02/27 Javascript
js中setTimeout的妙用--防止循环超时
2017/03/06 Javascript
JavaScript关联数组用法分析【概念、定义、遍历】
2017/03/15 Javascript
BootStrap+Mybatis框架下实现表单提交数据重复验证
2017/03/23 Javascript
vue学习笔记之vue1.0和vue2.0的区别介绍
2017/05/17 Javascript
ES6的解构赋值实例详解
2019/05/06 Javascript
vue-loader中引入模板预处理器的实现
2019/09/04 Javascript
JavaScript 判断浏览器是否是IE
2021/02/19 Javascript
python函数式编程学习之yield表达式形式详解
2018/03/25 Python
对Python中内置异常层次结构详解
2018/10/18 Python
python用plt画图时,cmp设置方法
2018/12/13 Python
Python运行异常管理解决方案
2020/03/09 Python
python实现五子棋程序
2020/04/24 Python
如何用Python绘制3D柱形图
2020/09/16 Python
Python如何使用ElementTree解析xml
2020/10/12 Python
Python使用Opencv实现边缘检测以及轮廓检测的实现
2020/12/31 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
奥地利顶级内衣丝袜品牌英国站:Wolford英国
2016/08/29 全球购物
加拿大在线隐形眼镜和眼镜店:VisionPros
2019/10/06 全球购物
nohup的用法
2012/11/26 面试题
企业新年寄语
2014/04/04 职场文书
道路交通事故人身损害赔偿协议书
2014/11/19 职场文书
作弊检讨书
2015/01/27 职场文书
医药公司开票员岗位职责
2015/04/15 职场文书
mysql多表查询-笔记七
2021/04/05 MySQL
Nginx开源可视化配置工具NginxConfig使用教程
2022/06/21 Servers
Rust中的Struct使用示例详解
2022/08/14 Javascript