注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Copper peas ' Bolg

Keep On Moving...This Is My Life...

 
 
 

日志

 
 

【原】 PHP 设计模式十六之状态设计模式  

2011-06-21 11:22:31|  分类: php |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

<?php
header("Content-type:text/html;charset=utf-8");
/**
 * 状态处理 状态设计模式
 * 定义:允许一个对象在其状态改变时,改变它的行为。看起来对象似乎修改了它的类。
 * @anthor Chen Wei Han <csq-3@163.com>
 * @copyright Chen Wei Han 2011-6-21上午09:36:08
 * @link http://csq-3.blog.163.com
 * @package demo
 * @version 1.0
 * 状态:A B C 三中状态切换
 */

/**
 * 抽象状态
 */
abstract class abstract_State
{
 abstract public function Handle($context); 
}


/**
 * 状态A
 */
class ConcreteStateA extends abstract_State
{
 private $state;
 
 public function __construct()
 {
  $this->state="A";
 }
 
 public function getstate()
 {
  return $this->state;
 }
 
 public function Handle($context)
 {
  echo $context->getstate()->getstate();
  $context->setstate(new ConcreteStateB());
 }
}

/**
 * 状态B
 */
class ConcreteStateB extends abstract_State
{
    private $state;
 
 public function __construct()
 {
  $this->state="B";
 }
 
    public function getstate()
 {
  return $this->state;
 }
 
 public function Handle($context)
 {
  echo $context->getstate()->getstate();
  $context->setstate(new ConcreteStateC());
 }
}

/**
 * 状态C
 */
class ConcreteStateC extends abstract_State
{
    private $state;
 
 public function __construct()
 {
  $this->state="C";
 }
 
    public function getstate()
 {
  return $this->state;
 }
 
 public function Handle($context)
 {
  echo $context->getstate()->getstate();
  $context->setstate(new ConcreteStateA());
 }
}

/**
 * 状态类切换
 */
class Context
{
 private $state;
 
 public function __construct($state)
 {
  $this->state = $state;
 }
 
 public function setstate($state)
 {
  $this->state = $state;
 }
 
 public function getstate()
 {
  return $this->state;
 }
 
 public function request()
 {
  $this->state->Handle($this);
 }
}


$c = new Context(new ConcreteStateA());
$c->request();
$c->request();
$c->request();
$c->request();

/**
 * 注:
 * 状态设计模式中的的状态都是设计好的,如果你想直接跳到C,那么只能循环过去
 * 而平时我们写的ifelse语句,你提供C状态,他会去执行C的分支,这是有区别的。
 * eg:
 * if($state="A"){}
 * else if($state="B"){}
 * else if($state="C"){}
 * else{}; (我举的状态设计模式例子:ABCA状态执行是有规律的,不要混淆)
 * 这种一般判断和上面的状态设计模式是有区别,状态设计模式适用于类似开关一样的状态切换,有一个变化规则在里面。
 * 比如一种文档流程状态执行:
 * 提交申请->待办->正在办->完成->上报->待批->正在批示->完成批示
 * 这样的状态是有规律的,就可以使用同一个查询接口,跟踪状态的进度,使用状态设计模式,一次执行不一定有。
 * 如果是一般无序的判断,而且必执行其一,如上面的eg A不行可能执行B,C或者其他,一次执行一定有想要的结果。
 * 根据实际情况可以使用策略或职责链设计模式
 * 下面分析一个比较混淆的案例

 A给B打电话的情况
 打电话返回状态:$state
 
   用户正常开机
   用户关机
   用户欠费停机
   用户消户
   无网络信息
   正在通话中
 很多人想到使用状态设计模式
 我这样问题你,返回信息如果是关机的类型,你状态设计模式怎么设计,你关机的下一个状态是什么,或许你想到没有就不显示下一个状态,显然这里使用状态设计模式是有问题的。
 显然打电话返回的类型,是一个无序的判断,跟状态没有关系,返回什么类型就是什么,也没有预定义的执行顺序。
 首先这里可以使用一个策略模式来判断,不同类型执行不同的策略方法。
 但如果用户接听后,这里就有一个有序的状态执行模式,这里就可以使用状态设计模式
 用户正常开机--->打通后计费(正在通话中)-->挂断结束计费(恢复用户正常开机)
 这里就是一个类似开关状态。
 */

  评论这张
 
阅读(148)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018