[Python设计模式] 第24章 加薪审批——职责链模式
github地址:https://github.com/cheesezh/python_design_patterns
题目
用程序模拟以下情景
- 员工向经理发起加薪申请,经理无权决定,需要向总监汇报,加薪额度超过总监权力范围,需要向总经理汇报;
- 员工还可以提交请加申请,经理可以决定2天以下的假,总监可以决定5天以下的假,其余都要上报总经理;
基础版本
class Request():
def __init__(self):
self.type = None # 申请类型
self.content = None # 申请内容
self.number = 0 # 申请数量
class Manager():
def __init__(self, name):
self.name = name
def get_result(self, manager_level, request):
if manager_level == "经理":
if request.type == "请假" and request.number <=2:
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
else:
print("{}:{} 数量 {} 我无权处理".format(self.name, request.content, request.number))
elif manager_level == "总监":
if request.type == "请假" and request.number <=5:
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
else:
print("{}:{} 数量 {} 我无权处理".format(self.name, request.content, request.number))
elif manager_level == "总经理":
if request.type == "请假":
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
elif request.type == "加薪" and request.number <= 500:
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
elif request.type == "加薪" and request.number > 500:
print("{}:{} 数量 {} 再说吧".format(self.name, request.content, request.number))
def main():
jingli = Manager("经理")
zongjian = Manager("总监")
zongjingli = Manager("总经理")
request = Request()
request.type = "加薪"
request.content = "贺贺请求加薪"
request.number = 1000
jingli.get_result(jingli.name, request)
zongjian.get_result(zongjian.name, request)
zongjingli.get_result(zongjingli.name, request)
request.type = "请假"
request.content = "贺贺请求请假"
request.number = 3
jingli.get_result(jingli.name, request)
zongjian.get_result(zongjian.name, request)
zongjingli.get_result(zongjingli.name, request)
main()
经理:贺贺请求加薪 数量 1000 我无权处理
总监:贺贺请求加薪 数量 1000 我无权处理
总经理:贺贺请求加薪 数量 1000 再说吧
经理:贺贺请求请假 数量 3 我无权处理
总监:贺贺请求请假 数量 3 被批准
总经理:贺贺请求请假 数量 3 被批准
点评
- Manager类的get_result方法比较长,有太多的分支判断,不是好的设计;
- Mangeer类有太多的责任,违背了单一职责的原则,增加新的管理者,需要修改这个类,违背了开放封闭原则;
职责链模式
职责链模式,使得多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止[DP]。
职责链模式基本结构
from abc import ABCMeta, abstractmethod
class Handler():
__metaclass__ = ABCMeta
def __init__(self):
self.successor = None # 设置继任者
@abstractmethod
def handle_request(self, request):
pass
class ConcretHandler1(Handler):
"""
处理0-10的请求
"""
def handle_request(self, request):
if request >=0 and request < 10:
print("handler1 handle request [ {} ]".format(request))
elif self.successor != None: # 由继任者处理请求
self.successor.handle_request(request)
class ConcretHandler2(Handler):
"""
处理10-20的请求
"""
def handle_request(self, request):
if request >=10 and request < 20:
print("handler2 handle request [ {} ]".format(request))
elif self.successor != None: # 由继任者处理请求
self.successor.handle_request(request)
class ConcretHandler3(Handler):
"""
处理20-30的请求
"""
def handle_request(self, request):
if request >=20 and request < 30:
print("handler3 handle request [ {} ]".format(request))
elif self.successor != None: # 由继任者处理请求
self.successor.handle_request(request)
def main():
h1 = ConcretHandler1()
h2 = ConcretHandler2()
h3 = ConcretHandler3()
h1.successor = h2
h2.successor = h3
requests = [2, 5, 14, 22, 18, 3, 27, 20]
for i in requests:
h1.handle_request(i)
main()
handler1 handle request [ 2 ]
handler1 handle request [ 5 ]
handler2 handle request [ 14 ]
handler3 handle request [ 22 ]
handler2 handle request [ 18 ]
handler1 handle request [ 3 ]
handler3 handle request [ 27 ]
handler3 handle request [ 20 ]
点评
- 当客户提交一个请求时,请求是沿着职责链传递直至有一个ConcretHandler对象负责处理它
- 接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构
- 职责链可以简化对象的相互链接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接收者的引用
- 可以随时增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性
- 一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理
- 最重要的两点
- 需要实现给每个具体管理者设置它的上司,也就是它的后继者
- 需要在每个具体管理者类处理请求时,做出判断,是可以处理请求,还是必须“推卸责任”,转移到后继者
职责链模式——加薪代码
from abc import ABCMeta, abstractmethod
class Manager():
__metaclass__ = ABCMeta
def __init__(self, name):
self.name = name
self.successor = None
@abstractmethod
def handle_request(self, request):
pass
class CommonManager(Manager):
def handle_request(self, request):
if request.type == "请假" and request.number <=2:
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
elif self.successor != None:
self.successor.handle_request(request)
class Majordomo(Manager):
def handle_request(self, request):
if request.type == "请假" and request.number <=5:
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
elif self.successor != None:
self.successor.handle_request(request)
class GeneralManager(Manager):
def handle_request(self, request):
if request.type == "请假":
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
elif request.type == "加薪" and request.number <= 500:
print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number))
elif request.type == "加薪" and request.number > 500:
print("{}:{} 数量 {} 再说吧".format(self.name, request.content, request.number))
def main():
jingli = CommonManager("经理")
zongjian = Majordomo("总监")
zongjingli = GeneralManager("总经理")
jingli.successor = zongjian
zongjian.successor = zongjingli
request = Request()
request.type = "加薪"
request.content = "贺贺请求加薪"
request.number = 1000
jingli.handle_request(request)
request.type = "请假"
request.content = "贺贺请求请假"
request.number = 3
jingli.handle_request(request)
main()
总经理:贺贺请求加薪 数量 1000 再说吧
总监:贺贺请求请假 数量 3 被批准
职责链模式和状态模式
- 职责链模式,主要处理requet和handler的问题,当handler收到requet时,判断是否自己是否可以处理,处理逻辑在handler中;
- 状态模式,主要处理state和context的问题,当state变化时,改变context的state,继续调用context的处理逻辑,处理逻辑在context中;
[Python设计模式] 第24章 加薪审批——职责链模式的更多相关文章
- Java设计模式(二十一):职责链模式
职责链模式(Chain Of Responsibility Pattern) 职责链模式(Chain Of Responsibility Pattern):属于对象的行为模式.使多个对象都有机会处理请 ...
- 设计模式(二十四)——职责链模式(SpringMVC源码分析)
1 学校 OA 系统的采购审批项目:需求是 采购员采购教学器材 1) 如果金额 小于等于 5000, 由教学主任审批 (0<=x<=5000) 2) 如果金额 小于等于 10000, ...
- 设计模式19:Chain Of Responsibility 职责链模式(行为型模式)
Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...
- [Python设计模式] 第28章 男人和女人——访问者模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 用程序模拟以下不同情况: 男人成功时,背后多半有一个伟大的女人: 女人成功 ...
- [Python设计模式] 第20章 挨个买票——迭代器模式
github地址:https://github.com/cheesezh/python_design_patterns 迭代器模式 迭代器模式,提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该 ...
- [Python设计模式] 第18章 游戏角色备份——备忘录模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 用代码模拟以下场景,一个游戏角色有生命力,攻击力,防御力等数据,在打Bos ...
- [Python设计模式] 第8章 学习雷锋好榜样——工厂方法模式
github地址:https://github.com/cheesezh/python_design_patterns 简单工厂模式 v.s. 工厂方法模式 以简单计算器为例,对比一下简单工厂模式和工 ...
- 《精通Python设计模式》学习行为型之责任链模式
感觉是全新的学习了. 因为在以前的工作中,并没有有意识的去运用哪一种编程模式. 以后要注意的了. 这才是高手之路呀~ class Event: def __init__(self, name): se ...
- 设计模式学习笔记——Chain of Responsibility职责链模式
重点在链.一条链,如果本节点处理不了,则传递给下一个节点处理. 关键是如何传给下一个节点? 主要是由本节点决定传给哪一个节点. public class Client { public static ...
随机推荐
- Python交互图表可视化Bokeh:7. 工具栏
ToolBar工具栏设置 ① 位置设置② 移动.放大缩小.存储.刷新③ 选择④ 提示框.十字线 1. 位置设置 import numpy as np import pandas as pd impor ...
- 007 numpy数组文件的存取
不知道这个有没有用,都整理了一番. 一:数组以二进制格式进行存储 1.说明 np.save与np.load是读写磁盘数组数据的两个重要函数. 默认情况下,数组以压缩的原始二进制格式保存在扩展名为npy ...
- Python多继承之MRO算法
MRO即Method Resolution Order 方法解析顺序,它的提出主要是为了解决Python中多继承时,当父类存在同名函数时,二义性的问题 下面先看一个例子: import inspe ...
- forward 和redirect
http://www.cnblogs.com/davidwang456/p/3998013.html
- android studio打可执行jar包
android studio可以通过library工程打出jar包 解压会看到META-INF/MANIFEST.MF文件的打开如下: Manifest-Version: 1.0 增加一行,注意冒号后 ...
- Django报错:提交表单报错---RuntimeError: You called this URL via POST, but the URL doesn’t end in a slash and you have APPEND_SLASH set.
Django报错:提交表单报错---RuntimeError: You called this URL via POST, but the URL doesn’t end in a slash and ...
- 李宏毅机器学习笔记4:Brief Introduction of Deep Learning、Backpropagation(后向传播算法)
李宏毅老师的机器学习课程和吴恩达老师的机器学习课程都是都是ML和DL非常好的入门资料,在YouTube.网易云课堂.B站都能观看到相应的课程视频,接下来这一系列的博客我都将记录老师上课的笔记以及自己对 ...
- DataGridView获取或者设置当前单元格的内容
当前单元格指的是DataGridView焦点所在的单元格,它可以通过DataGridView对象的CurrentCell属性取得.如果当前单元格不存在的时候,返回null. 取得当前单元格的内容: o ...
- Hibernate中Restrictions查询用法(转)
Restrictions查询用法 HQL运算符 QBC运算符 含义 = Restrictions.eq() 等于equal <> Restrictions.ne() 不等于not equa ...
- 面试题fugui02
一.概念题 1.描述对super.pass.yield.lambda关键字修饰的理解 2.大致描述一下python GIL的机制,以及python中多线程和多进程的区别 GIL全局解释器锁,是pyth ...