PHP设计模式——状态模式

前言

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

效果图

图片描述

需求分析

一、代码遵循可拓展性强,可维护性强,复用性强,杜绝”牵一发而动全身”的状况。
二、减小使用大量的if、else if、switch判断。设计模式

核心代码

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

<?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);  
    }  
}

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

<?php
namespace common\status;

//状态接口  
interface IState  
{  
    public function WriteCode($w);  
}

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

//早晨工做状态  
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');  
    }  
}

调用客户端代码

<?php

use common\status\Work;
//问候语
$emergWork = new Work();  
$emergWork->hour = date("H");  
$call=$emergWork->WriteCode();

增长状态

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

<?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.二、新增一个半夜工做状态类,里面写要执行的行为。设计

<?php  
namespace common\status;

use Yii;
use common\status\IState;

//半夜工做状态  
class Midnight implements IState  
{ 
    public function WriteCode($w)  
    { 
        return Yii::t('yii','midnight');   
    }  
}

怎么样,增长一个状态是否是很简单?拓展性很是好。code

提醒注意

一、实现状态接口类中的$w->WriteCode()必需要return返回,不然调用客户端代码的时候没法赋值给$call,会直接echo输出。
二、实现状态接口类中的public function WriteCode($w)方法里的$w对象类应该是Work对象,不能是当前类的对象。对象

总结分析

一、优势
1.一、状态模式将与特定状态相关的行为局部化,而且将不一样状态的行为分割开来。
1.二、全部状态相关的代码都存在于某个ConcereteState中,因此经过定义新的子类很容易地增长新的状态和转换。
1.三、状态模式经过把各类状态转移逻辑分不到State的子类之间,来减小相互间的依赖。
二、缺点
2.一、致使较多的ConcreteState子类。blog

相关资料

状态模式

相关文章
相关标签/搜索