PHP设计模式——状态模式

允许对象在其内部状态更改时更改其行为。 该对象似乎将更改其类。

John在一家受欢迎的电话支持公司中担任客户支持代表。 在以客户服务为导向的公司中,公司的首要任务是确保客户满意。 为了改善服务质量,该公司投入了大量资金来改善支持代表的服务。 最近的研究表明,支持代表的情绪会影响他们在工作中的表现。 John本人承认,接听电话时的前几句话通常可以表明他所处的心情。当他心情愉快时,通常会向顾客打招呼“嗨!”或“你好,怎么样”。 我可以帮您吗?”当他生气且情绪低落时,他的回答是打招呼“你好”或“是?”。如果John情绪温和,则他将用“嗨”或“你好”柔和的和一个人打开对话。

让我们将以上的信息放入代码中:

class SupportRep
{
    private $_state =  "happy";
    public function setState($state)
    {
        $this->_state = $state;
    }
 
    public function sayHi()
    {
        if ($this->_state=='happy') {
            echo 'hi there!';
        } else if ($this->_state=='angry') {
            echo 'yes?';
        } else if ($this->_state=='moderate') {
            echo 'hi';
        }
    }
}

上面的代码非常简单明了,可以帮助我们研究支持代表的行为。 但是,随着研究的进展和更多信息的引入,该代码可能还不够。 研究表明,一个人的情绪会根据他打过的电话的数量以及当前的情绪而改变。

当John接听五到十个电话时,他的心情将从“快乐”变为“温和”,这可能是因为他感到疲倦或承受着压力。 如果他接到10个以上的电话,他的心情将从“温和”变为“愤怒”,处理太多的支持电话确实很麻烦。

让我们重新编写代码以添加以上的逻辑:

class SupportRep
{
    private $_state =  null;
    public  $numOfCalls = 0;
    public function setState($state)
    {
        $this->_state = $state;
    }
 
    public function sayHi()
    {
        if ($this->_state=='happy') {
            echo 'hi there!';
            if ($this->numOfCalls>5&&$this->numOfCalls<10) {
                $this->setState('moderate');
            }
            if ($this->numOfCalls>10) {
                $this->setState('angry');
            }
        } else if ($this->_state=='angry') {
            echo 'yes?';
        } else if ($this->_state=='moderate') {
            echo 'hi';
            if ($this->numOfCalls>10) {
                $this->setState('angry');
            }
        }
        $this->numOfCalls;
    }
}

你发现上面的代码有什么问题吗? 不,它没有什么错,除了一堆的if-else的语句。 对于我们来说,它甚至看起来都不是面向对象的,最糟糕的是它明显违反了单一责任原则(SRP)。 此类更改的原因有多种。 当你对快乐状态,温和状态或愤怒状态有其他逻辑时。 它引入了代码修改,并且记住我们在这里只是在谈论sayHi()函数。 当基于情绪的条件适用于其他岗位的各个方面时,会发生什么?

是时候改变了。 在这种情况下,我们就需要使用状态模式(State Pattern)。 状态模式使我们可以封装变化的部分,即sayHi函数。 具体取决于支持代表的心情。

首先,让我们创建一个状态接口(StateInterface),所有后续状态都必须实现它:

interface StateInterface
{
   public function sayHi();
}

然后,我们将创建三个状态的类,每个类都实现自己的逻辑:

class AngryState implements StateInterface
{
    private $_supportRep = null;
    public function __construct(SupportRep $supportRep)
    {
        $this->_supportRep = $supportRep;
    }
    public function sayHi()
    {
        echo 'yes?';
    }
}
 
class ModerateState implements StateInterface
{
    private $_supportRep = null;
    public function __construct(SupportRep $supportRep)
    {
        $this->_supportRep = $supportRep;
    }
    public function sayHi() {
        echo 'hi';
        if ($this->_supportRep->numOfCalls>10) {
            $this->_supportRep->setState(new AngryState($this->_supportRep
        ));
        }
    }
}
 
class HappyState implements StateInterface
{
    private $_supportRep = null;
    public function __construct(SupportRep $supportRep)
    {
        $this->_supportRep = $supportRep;
    }
 
    public function sayHi()
    {
        echo 'hi there!';
        if ($this->_supportRep->numOfCalls>5&&$this->_supportRep->numOfCalls<10) {
        Rep));
    ));
    }
}

最后,我们来重构下支持代表的类SupportRep

class SupportRep
{
    private $_state =  null;
    public  $numOfCalls = 0;
    public function __construct()
    {
        $this->_state = new ModerateState($this);
    }
 
    public function setState($state)
    {
        $this->_state = $state;
    }
 
    public function sayHi()
    {
        $this->_state->sayHi();
        $this->numOfCalls++;
    }
}

如你所见,SupportRep类的sayHi()函数将其职责委托给状态类。 它不再违反单一责任原则(SRP)。 三个状态类仍然可以通过组合来更改主要类的状态。

现在,SupportRep变得更加整洁,如果需要添加任何其他逻辑,则可以将其作为单独的状态类来完成。 SupportRep的其他功能可以委托给状态类。

在我们的示例中,状态模式允许对象(SupportRep对象)在其内部状态更改(在HappyStateModerateStateAngryState之间切换)时更改其行为(各个状态类中的sayHi()函数)。

你可能感兴趣的:(PHP设计模式——状态模式)