python设计模式第二十三天【状态模式】
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设计模式第二十三天【状态模式】的更多相关文章
- python设计模式第二十二天【备忘录模式】
1.应用场景 (1)能保存对象的状态,并能够恢复到之前的状态 2.代码实现 #!/usr/bin/env python #! _*_ coding:UTF-8 _*_ class Originator ...
- python设计模式之模型-视图-控制器模式
python设计模式之模型-视图-控制器模式 关注点分离( Separation of Concerns, SoC)原则是软件工程相关的设计原则之一. SoC原则背后的思想是将一个应用切分成不同的部分 ...
- Java设计模式(19)状态模式(State模式)
State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...
- Javascript设计模式之我见:状态模式
大家好!本文介绍状态模式及其在Javascript中的应用. 模式介绍 定义 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是控制一个对象状态的条件表达式 ...
- 【设计模式 - 20】之状态模式(State)
1 模式简介 状态模式的定义: 状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类.这个模式将状态封装成独立的类,并将动作委托到代表当前状态的类的对象. 状态模式的优点 ...
- 《Head First 设计模式》学习笔记——状态模式
在软件开发过程中.应用程序可能会依据不同的情况作出不同的处理. 最直接的解决方式是将这些全部可能发生的情况全都考虑到.然后使用if... ellse语句来做状态推断来进行不同情况的处理. 可是对复杂状 ...
- C#设计模式之十九状态模式(State Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第六个模式,该模式是[状态模式],英文名称是:State Pattern.无论是现实世界,还是面向对象的OO世界,里面都有一个东西, ...
- C#设计模式之十八状态模式(State Pattern)【行为型】
一.引言 今天我们开始讲“行为型”设计模式的第六个模式,该模式是[状态模式],英文名称是:State Pattern.无论是现实世界,还是面向对象的OO世界,里面都有一个东西,那就是对象.有对象当然就 ...
- 设计模式(java)--状态模式
状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要 ...
随机推荐
- solidity learning (1)
学习文档笔记:http://solidity-cn.readthedocs.io/zh/develop/layout-of-source-files.html 1.pragma solidity ^0 ...
- ganache与metamask
1.其实ganache其实就相当于一个私有链ganache安装,这个是图形化界面的: 2.(testRpc跟他其实是一个用处,有一个即可,只不过testRpc是非图形化界面.要注意两者都仅运行在內存中 ...
- HTTP协议、HTTP请求方法、常见状态码、HTTP消息
HTTP协议 客户端请求,服务端响应.浏览器与服务器不建立持久连接,响应后连接失效. HTTP请求方法 一.GET GET方法用于获取请求页面的指定信息. 二.HEAD 除了服务器不能在响应里返回消息 ...
- P1171 售货员的难题--搜索(剪枝)
题目背景 数据有更改 题目描述 某乡有nn个村庄(1<n \le 201<n≤20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)s(0<s ...
- Mybatis学习总结(五)——动态sql
MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格,还要注意省掉 ...
- RPC通信原理(未完,先睡觉)
一 背景 OpenStack 各组件之间是通过 REST 接口进行相互通信,比如Nova.Cinder.Neutron.Glance直间的通信都是通过keystone获取目标的endpoint,即ap ...
- org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
项目启动报错2018-12-21 14:06:24.917 INFO 23472 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refr ...
- 分布式架构的基石.简单的 RPC 框架实现(JAVA)
前言 RPC 的全称是 Remote Procedure Call,它是一种进程间通信方式.允许像调用本地服务一样调用远程服务. 学习来源:<分布式系统架构:原理与实践> - 李林锋 1. ...
- 分享一个公众号h5裂变吸粉源码工具
这次我是分享我本人制作的一个恶搞程序,说白了就是一个公众号裂变吸粉工具,市面上有很多引流方法,例如最常见的就是色流,哈哈,今天我跟大家分享的方法是有趣的,好玩的,恶搞的.这个程序上线一天已经收获了61 ...
- springmvc的@ResponseBody报错
错误:差不多就是下面的格式 原因:你可能返回的类型是这样的List<School>而school类中可能包含Class类或者Teacher类,就是包含对象. 这样的话jackson是不能帮 ...