4.php设计模式:状态模式的使用场景

在这儿给大家说点事儿。我的博客搬家到github主页上了。我的博客。以后首发都在github上了。csdn也会继续更新。可能就是稍微慢一下。

另外最近搞了一个支付的开源项目。这是项目地址 目前已经支持:
* 支付宝的 即时到帐、移动支付、加密退款接口。
* 微信的目前已经支持:app支付、扫码支付、H5支付

项目还存在些bug,正在不断结合公司业务进行修改。后期可能会支持的越来越全面。

状态模式

废话不多说了,回到本文主题: 状态模式

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

说实话,这定义真JB不是怎么读的懂。不过咱要试着去理解其中的精髓。谁让咱们有颗向上的心呢?

一句句来。

先说这一句: 允许一个对象在其内部状态改变时改变它的行为


class Context {
    private $state;

    public function __construct($state)
    {
        $this->state = $state;
    }

    public function change()
    {
        if ($this->state == 1) {
            echo '我是好人';
        } elseif ($this->state == 2) {
            echo '我要当坏人';
        } elseif (...) {
            // 其他状态
        }
        else {
            echo '爱好和平!';
        }
    }
}

以下我要开始自己的理解了,这个理解不一定是上面定义的本意,但是绝对讲人话,有帮助,可实战。

如果 state 传入的值不同,则会得到不同的行为。那么这就是我理解的这一句话的意思。再说白话一点,根据不同的条件,执行不同的逻辑。

对象看起来似乎修改了它的类 这一句更扯淡,真不知道这些人怎么想的,就不能说的通俗些?我觉得嘛,这个概念能懂就懂,不懂呢,你就这么办:那就是对于每一个条件中的逻辑,移入到不同的类中,这些类要实现一个统一的接口。还不懂?上代码


interface State()
{
    // 注意这里的Context 我在后面会讲到。不等同于上面的 Context 类哦
    public function handle(Context $context);
}

// 状态A
class StateA implements State
{
    public function handle(Context $context)
    {
        if ($context->term = 1) {
            // 处理逻辑,并终止程序
        } else {
            $context.setState(new StateB());
        }
    }
}

// 状态B
class StateB implements State
{
    public function handle(Context $context)
    {
        if ($context->term = 2) {
            // 处理逻辑,并终止程序
        } else {
            $context.setState(new StateC());
        }
    }
}

// 状态C
class StateC implements State
{
    public function handle(Context $context)
    {
        // 如果还有其他状态,则继续往下走。如果没有,就在次终止程序
    }
}


// 新的Context类的实现
class Context
{
    private $state;// 用来保存 State 对象

    public function setState(State $state)
    {
        $this->state = $state;
    }

    public function request()
    {
        $this->state->handle($this);
    }
}

上面的代码基本上就已经演示了 状态模式 。有看官急了,写的什么狗屎?怎么用,哪儿可以用?别急,等我把这个逼装完。

模式类图

继续装逼,上类图。

类图

从这个图中可以看出,纯种的状态模式,包括了以下三个角色:

  • Context: 环境类。它呢需要在代码中传给具体的 State 类,这样State类才能改变它。记得这句 对象看起来似乎修改了它的类 吗?就着这句话再去理解下这个类。他保存有当前的状态。
  • State: 抽象的状态接口 。让具体的状态都要实现这个接口,Context依赖接口进行编程。
  • ConcreteState: 具体的状态类。专门用于处理某一个状态,如果处理不了就转发出去。

使用场景

上面讲那么多,不能真刀真枪的用到项目中,都是耍流氓。在我们的项目中其实有特别多的地方可以用到状态模式。

  • 如果项目中存在太多的 if {...} elseif {...} else {...} 。那么你应该考虑状态模式。我觉得这个是重点考虑对象
  • 如果每个状态中处理的业务逻辑特别复杂·那么建议考虑这种方式。
  • 最后一点,如果代码中的状态相对固定。比如一个电商中购买商品的流程:未支付、已过期、待发货(已支付)、已发货、已收货。那么这种状态基本上定下来不会有太大变化,状态发生在内部中,顺序固定,不需要客户端进行处理。

以上三种情况是我建议的方式。如果大家还有总结的经验,欢迎分享。

这里有个问题,待我写完 职责链模式 之后再来分享。因为这二者有相当多的共同之处。大家一定认真阅读我写的 使用场景 的最后一点。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值