1.应用场景

(1)通过改变对象的内部状态从而改变对象的行为,一般表现为状态的顺序执行

2.代码实现

#!/usr/bin/env python
#!_*_ coding:UTF-8 _*_

from abc import ABCMeta, abstractmethod

class Context(object):

    def __init__(self):
        self.state = ConditionOneState(self)

    def request(self):
        '''上下文的请求'''
        self.state.handle(self)

class State(object):

    __metaclass__ = ABCMeta

    def __init__(self, context):
        self.context = context

    @abstractmethod
    def handle(self):
        pass

class ConditionOneState(State):

    def handle(self, context):
        '''状态1的处理'''
        if context.condition == "condition1":
            print "handle condition1"
        else:
            context.state = ConditionTwoState(context)
            context.request()

class ConditionTwoState(State):

    def handle(self, context):
        if context.condition == "condition2":
            print "handle condition2"
        else:
            context.state = ConditionThreeState(context)
            context.request()

class ConditionThreeState(State):

    def handle(self, context):
        '''状态2的处理'''
        if context.condition == "condition3":
            print "handle condition3"
        else:
            context.state = UnkownState(context)
            context.request()

class UnkownState(State):

    def handle(self, context):
        '''未知状态'''
        print "unkown state"

if __name__ == "__main__":
    context = Context()

    context.condition = "condition1"
    context.request()

    context.condition = "condition2"
    context.request()

    context.condition = "condition3"
    context.request()

    context.condition = "condition1"
    context.request()

结果:

/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23_state/state_test.py
handle condition1
handle condition2
handle condition3
unkown state

Process finished with exit code 0

注意:

(1)处理的过程如下所示:

state1=====condition1========handle1

state1=====condition2========置为下一个状态

state2=====condtion2========handle2

state2=====conditon3========置为下一个状态

state3=====condition3========handle3

state3=====condtion1=========置为下一个状态

unkownstate======condition1=======handle_unkown

3. 实战(使用php的Yii2框架实现库存盘点单据的作废及提示)

业务需求:

(1)若库存盘点已经作废则不能再次作废

(2)若库存盘点单据已经生成报损报溢单据则不能作废提示先删除报损报溢单据

(3)其他情况可以作废

<?php
namespace core\models;

use \core\models\WmsProfitloss;

class WmsCheckDeleterContext{
    /**
     * @var
     * 使用状态模式二实现库存盘点的作废功能; 库存盘点单据的状态有可能为未作废,已生成报损报溢单据且报损报溢单据未作废;库存盘点已经作废
     */
    private $__wmsCheckModel;
    //这里增加状态的引用
    private $__state;

    public function __construct($wmsCheckModel)
    {
        $this->wmsCheckModel = $wmsCheckModel;
        $__isDel = $this->wmsCheckModel->is_del;
        $__wmsProfitlossModelExists = WmsProfitloss::find()->where(['wms_profitloss_union_code'=>$this->wmsCheckModel->wms_check_code, 'is_del'=>0])->exists();

        //这里判断状态类的创建对象
        if ($__isDel){
            $__state = new AlreadyDeletedState($wmsCheckModel);
        }elseif($__wmsProfitlossModelExists){
            if ($__wmsProfitlossModelExists){
                $__wmsProfitlossModels = WmsProfitloss::find()->where(['wms_profitloss_union_code'=>$this->wmsCheckModel->wms_check_code, 'is_del'=>0])->all();
            }
            $__state = new NotDeletedButProfitlossStatus($__wmsProfitlossModels);
        }else{
            $__state = new NotDeletedNotProfitlossStatus($wmsCheckModel);
        }
        $this->__state = $__state;
    }

    /**
     * @param State $state
     * 设置引用的状态对象
     */
    public function setState(State $state){
        $this->__state = $state;
    }

    /**
     * @return AlreadyDeletedState|NotDeletedButProfitlossStatus|NotDeletedNotProfitlossStatus
     * 获取引用的转态对象
     */
    public function getState(){
        return $this->__state;
    }

    /**
     * @return array
     * 作废前准备检测作废状态
     */
    public function requestDeletePrepare(){
        return $this->getState()->prepare();
    }

    /**
     * @return array
     * 作废请求
     */
    public function requestDelete(){
        return $this->getState()->handle();
    }
}

/**
 * Interface State
 * @package core\models
 * 状态类的抽象接口类,定义准备方法和实际处理方法
 */
interface State{
    public function prepare();
    public function handle();
}

class NotDeletedNotProfitlossStatus implements State {
    public function __construct($wmsCheckModel)
    {
        $this->__wmsCheckModel = $wmsCheckModel;
    }

    public function prepare(){
        return ['status'=>true, 'errcode'=>'', 'errmsg'=>'你确定要作废库存盘点单据'.$this->__wmsCheckModel->wms_check_code.'吗?作废后不可恢复'];
    }
    public function handle()
    {
        $deleteResult = $this->__wmsCheckModel->delete();
        if (!$deleteResult){
            return ['status'=>false, 'errcode'=>'', 'errmsg'=>'作废库存盘点单据'.$this->__wmsCheckModel->wms_check_code.'失败'];
        }else{
            return ['status'=>true, 'errcode'=>'', 'errmsg'=>'作废库存盘点单据'.$this->__wmsCheckModel->wms_check_code.'成功'];
        }
    }
}

class NotDeletedButProfitlossStatus implements State{
    public function __construct($wmsProfitlossModels)
    {
        $this->__wmsProfitlossModels = $wmsProfitlossModels;
    }

    public function prepare(){
        $__code_list = \yii\helpers\ArrayHelper::getColumn($this->__wmsProfitlossModels, 'wms_profitloss_code');
        $__code_str = implode(',', $__code_list);
        return ['status'=>false, 'errcode'=>'', 'errmsg'=>'请先作废报损报溢单据'.$__code_str];
    }

    public function handle()
    {
        return $this->prepare();
    }
}

class AlreadyDeletedState implements State{
    public function __construct($wmsCheckModel)
    {
        $this->__wmsCheckModel = $wmsCheckModel;
    }
    public function prepare(){
        return ['status'=>false, 'errcode'=>'', 'errmsg'=>'库存盘点单据'.$this->__wmsCheckModel->wms_check_code.'已经作废,无需再次作废'];
    }
    public function handle()
    {
        return $this->prepare();
    }
}

python设计模式第二十三天【状态模式】的更多相关文章

  1. python设计模式第二十二天【备忘录模式】

    1.应用场景 (1)能保存对象的状态,并能够恢复到之前的状态 2.代码实现 #!/usr/bin/env python #! _*_ coding:UTF-8 _*_ class Originator ...

  2. python设计模式之模型-视图-控制器模式

    python设计模式之模型-视图-控制器模式 关注点分离( Separation of Concerns, SoC)原则是软件工程相关的设计原则之一. SoC原则背后的思想是将一个应用切分成不同的部分 ...

  3. Java设计模式(19)状态模式(State模式)

    State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...

  4. Javascript设计模式之我见:状态模式

    大家好!本文介绍状态模式及其在Javascript中的应用. 模式介绍 定义 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是控制一个对象状态的条件表达式 ...

  5. 【设计模式 - 20】之状态模式(State)

    1      模式简介 状态模式的定义: 状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类.这个模式将状态封装成独立的类,并将动作委托到代表当前状态的类的对象. 状态模式的优点 ...

  6. 《Head First 设计模式》学习笔记——状态模式

    在软件开发过程中.应用程序可能会依据不同的情况作出不同的处理. 最直接的解决方式是将这些全部可能发生的情况全都考虑到.然后使用if... ellse语句来做状态推断来进行不同情况的处理. 可是对复杂状 ...

  7. C#设计模式之十九状态模式(State Pattern)【行为型】

    一.引言   今天我们开始讲"行为型"设计模式的第六个模式,该模式是[状态模式],英文名称是:State Pattern.无论是现实世界,还是面向对象的OO世界,里面都有一个东西, ...

  8. C#设计模式之十八状态模式(State Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第六个模式,该模式是[状态模式],英文名称是:State Pattern.无论是现实世界,还是面向对象的OO世界,里面都有一个东西,那就是对象.有对象当然就 ...

  9. 设计模式(java)--状态模式

    状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要 ...

随机推荐

  1. A. Many Equal Substrings(水题)

    思路: 直接比较橘色框里的取第一次相等,即可. #include<iostream> #include<string> using namespace std; string ...

  2. $.each遍历实现延时

    今天做项目时需要一功能,如题..... $.each(json, function(idx, obj) { setTimeout(function () {downloadFile(obj.fileK ...

  3. ESP8266串口和MQTT服务器消息互传(版本一) 单纯透传+保存WIFI账号信息

    目标 制作一个ESP8266串口和MQTT相互透传的小WIFI,可用手机修改其连接的路由器,由此该模块可以任意加载到各种串口传输的单片机上,完成硬件到云端的传输. 1 实物图 2 MQTT网页测试客户 ...

  4. JDK动态代理(1)-----------new 对象的方式

    //case 1: 直接newHelloWorldImpl helloWorldImpl = new HelloWorldImpl(); //case 2: 反射拿到类之后,通过newInstance ...

  5. oracle 创建表空间TABLESPACE

    题外话: 在oracle中,我们的数据库用户都有一个默认表空间归属,当在该用户下创建表或其他对象时默认会将其归属在默认表空间: 不排除后期修改了用户默认表空间的情况存在,此后新加入的对象默认会放置在新 ...

  6. 用C# 模拟实现unity里的协程

    注:需要了解C#的迭代器,不然很难理解. 之前面试有被问到unity协程的原理,以及撇开unity用纯C#去实现协程的方法.后来了解一下,确实可以的.趁这会有空,稍微总结一下. 还是结合代码说事吧: ...

  7. bootstrap 失效的原因

    首先必须对着官方文档的模板来写: https://getbootstrap.com/docs/4.3/getting-started/introduction/ 然后: 这里必须加上 rel=&quo ...

  8. 支持异步同步的分布式CommandBus MSMQ实现 - 支持Session传递、多实例处理

    先上一张本文所描述的适用场景图 分布式场景,共3台server: 前端Server Order App Server Warehouse App Server 功能: 前端Server可以不停的发送C ...

  9. 程序员修仙之路- CXO让我做一个计算器!!

    菜菜呀,个税最近改革了,我得重新计算你的工资呀,我需要个计算器,你开发一个吧 CEO,CTO,CFO于一身的CXO X总,咱不会买一个吗? 菜菜 那不得花钱吗,一块钱也是钱呀··这个计算器支持加减乘除 ...

  10. 阿里巴巴2017实习生招聘模拟题(部分)---C++后台开发方向

    1.一个机器人玩抛硬币的游戏,一直不停的抛一枚不均匀的硬币,硬币有A,B两面,A面的概率为3/4,B面的概率为1/4.问第一次出现连续的两个A年的时候,机器人抛硬币的次数的期望是多少? 9/4 11/ ...