设计模式 状态模式

106 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。 image.png

介绍

shiyanlou:状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。有时,一个对象的行为受其一个或多个具体的属性变化而变化,这样的属性也叫作状态,这样的的对象也叫作有状态的对象。

角色

角色说明
Context环境类,维护一个 ConcreteState 子类的实例,这个实例定义当前状态
State抽象状态类,定义一个接口以封装与 Context 的一个特定状态相关的行为
ConcreteState具体状态类,每一个子类实现一个与 Context 的一个状态相关的行为

角色示例

类名担任角色说明
VipContext会员类
LevelState会员等级类
Level1ConcreteState等级一
Level2ConcreteState等级二
Level3ConcreteState等级三

UML类图

image.png

代码

<?php 
class Vip{
    protected $level;

    protected static $money = 0;

    function __construct()
    {
        $this->level = Level1::getInstance();
    }

    public function changeLevel()
    {
        $money = $this->money;
        switch ($money) {
            case  ($money >= 0 && $money < 5):
                $this->level = Level1::getInstance();
                break;
            case  ($money >= 5 && $money < 10):
                $this->level = Level2::getInstance();
                break;
            case  ($money >= 10):
                $this->level = Level3::getInstance();
                break;
        }
        return '变更'.get_class($this->level).PHP_EOL;
    }

    public function deposit($money)
    {
        $this->money += $money;
        return '充值'.$money.',余额'.$this->money.','.$this->level->check($this);
    }
}

abstract class Level{

    abstract function check(Vip $vip);

}


class Level1 extends Level
{
    private static $instance;

    private function __construct(){}

    private function __clone(){}

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function check(Vip $vip)
    {
        return $vip->changeLevel();
    }
}

class Level2 extends Level
{
    private static $instance;

    private function __construct(){}

    private function __clone(){}

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function check(Vip $vip)
    {
        return $vip->changeLevel();
    }
}

class Level3 extends Level
{
    private static $instance;

    private function __construct(){}

    private function __clone(){}

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function check(Vip $vip)
    {
        return $vip->changeLevel();
    }
}

$vip = new Vip();
echo $vip->deposit(3);
echo $vip->deposit(6);
echo $vip->deposit(9);

创建 Vip.php,内容如上。

执行

$ php Vip.php
充值3,余额3,变更Level1
充值6,余额9,变更Level2
充值9,余额18,变更Level3