设计模式 - 状态模式

来源:互联网 发布:wps可以在mac上用吗 编辑:程序博客网 时间:2024/06/16 21:56

前言

状态设计模式是Gof提出的最吸引人的模式之一,也是一种最有用的模式。游戏通常就采用状态模式,因为游戏中的对象往往会非常频繁地改变状态。状态模式的作用就是允许对象在状态改变时改变其行为。还有很多其他模拟应用(不一定是游戏)也依赖于状态模式。本文将会谈到并举例说明。
按照传统思维,如果有多个状态的话一般就是用if、else if、switch处理了,但是这类的代码看起来极其不美观,最重要的是没什么拓展性,维护性,复用性,还会出现“牵一发而动全身”的情况。如果把这些状态封装起来,就可以减少大量的判断,那么就要用状态模式了。

效果图

这里写图片描述

需求分析

1、代码遵循可拓展性强,可维护性强,复用性强,杜绝”牵一发而动全身”的情况。
2、减少使用大量的if、else if、switch判断。

核心代码

1、Work.php(它定义了时间程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的具体对象来处理。)

<?php namespace common\status;//工作状态  class Work  {      private $current;      public $hour;    public function __construct()      {          $this->current = new EarlyMorning();      }    //设置状态      public function SetState($s)      {        $this->current = $s;      }      public function WriteCode()      {        return $this->current->WriteCode($this);      }  }  

2、IState.php(定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。)

<?phpnamespace common\status;//状态接口  interface IState  {      public function WriteCode($w);  }  

3、EarlyMorning.php(实现抽象状态定义的接口。)

//早晨工作状态  class EarlyMorning implements IState  {     public function WriteCode($w)      {          if($w->hour<6)          {             return Yii::t('yii','Good Early morning');         }else{              $w->SetState(new GoodMorning());             return $w->WriteCode();  //注意:这里必须都要return返回,否则调用客户端代码的时候无法赋值给$call。        }       }  } //早上工作状态  class GoodMorning implements IState  {     public function WriteCode($w)      {          if($w->hour<9)          {             return Yii::t('yii','Good morning');         }else{              $w->SetState(new GoodForenoon());             return $w->WriteCode();          }        }  } //上午工作状态  class GoodForenoon implements IState  {     public function WriteCode($w)      {           if($w->hour<12)          {            return Yii::t('yii','Good forenoon');         }else{              $w->SetState(new GoodNoon());             return $w->WriteCode();          }        }  } //中午工作状态  class GoodNoon implements IState  {     public function WriteCode($w)      {         if($w->hour<14)          {             return Yii::t('yii','Good noon');         }else{              $w->SetState(new GoodAfternoon());             return $w->WriteCode();          }        }  } //下午工作状态  class GoodAfternoon implements IState  {     public function WriteCode($w)      {          if($w->hour<17)          {             return Yii::t('yii','Good afternoon');         }else{              $w->SetState(new GoodDusk());             return $w->WriteCode();          }        }  }//傍晚工作状态  class GoodDusk implements IState  {     public function WriteCode($w)      {         if($w->hour<19)          {             return Yii::t('yii','Good dusk');         }else{              $w->SetState(new GoodNight());             return $w->WriteCode();          }       }  } //晚上工作状态  class GoodNight implements IState  {     public function WriteCode($w)      {          if($w->hour<22)          {             return Yii::t('yii','Good night');         }else{              $w->SetState(new GoodAtNight());             return $w->WriteCode();          }       }  } //夜里工作状态  class GoodAtNight implements IState  {     public function WriteCode($w)      {          return Yii::t('yii','Good at night');      }  }   

调用客户端代码

<?phpuse commonstatusWork;//问候语$emergWork = new Work(); $emergWork->hour = date("H"); $call=$emergWork->WriteCode();

增加状态

1、例如:在原来的应用中增加个“半夜的状态”。
1.1、在原夜里工作状态类增加个if判断,符合条件时调用半夜的工作状态。

<?php  namespace common\status;use Yii;use common\status\IState;//夜里工作状态  class GoodAtNight implements IState  {     public function WriteCode($w)      {          if($w->hour<23)          {               return Yii::t('yii','Good at night');          }else{              $w->SetState(new Midnight());              return  $w->WriteCode();          }       }  }

1.2、新增一个半夜工作状态类,里面写要执行的行为。

<?php  namespace common\status;use Yii;use common\status\IState;//半夜工作状态  class Midnight implements IState  {     public function WriteCode($w)      {         return Yii::t('yii','midnight');       }  }

怎么样,增加一个状态是不是很简单?拓展性非常好。

提醒注意

1、实现状态接口类中的w>WriteCode()returncall,会直接echo输出。
2、实现状态接口类中的public function WriteCode(w)w对象类应该是Work对象,不能是当前类的对象。

总结分析

1、优点
1.1、状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
1.2、所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换。
1.3、状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。
2、缺点
2.1、导致较多的ConcreteState子类。

相关资料
PHP设计模式-状态模式
CSDN PHP设计模式-状态模式

0 0