Python设计模式——行为型模式

news/2024/11/30 5:58:51/

目录

    • 责任链模式
    • 观察者模式
    • 策略模式
    • 模板方法模式

责任链模式

  • 内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
  • 角色
    • 抽象处理者(Handler)
    • 具体处理者(ConcreteHandler)
    • 客户端(Client)
from abc import ABCMeta, abstractmethodclass Handler(metaclass=ABCMeta):@abstractmethoddef handle_leave(self, day):passclass GeneralManager(Handler):def handle_leave(self, day):if day < 10:print(f"总经理准假{day}天")else:print("你还是辞职吧")class DepartmentManager(Handler):def __init__(self):self.next = GeneralManager()def handle_leave(self, day):if day < 7:print(f"部门经理准假{day}天")else:print("部门经理职权不够,交给总经理处理")self.next.handle_leave(day)class ProjectDirector(Handler):def __init__(self):self.next = DepartmentManager()def handle_leave(self, day):if day < 3:print(f"项目主管准假{day}天")else:print("项目主管职权不够,交给部门经理处理")self.next.handle_leave(day)# 客户端
day = 4
h = ProjectDirector()
h.handle_leave(day)
项目主管职权不够,交给部门经理处理
部门经理准假4天
  • 适用场景:
    • 有多个对象可以处理一个请求,哪个对象处理由运行时决定
    • 在不明确接收者的情况下,向多个对象中的一个提交一个请求
  • 优点:
    • 降低耦合度:一个对象无需知道是其他哪一个对象处理其请求

观察者模式

  • 内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式又称“发布-订阅”模式
  • 角色
    • 抽象主题(Subject)
    • 具体主题(ConcreteSubject)————发布者
    • 抽象观察者(Observer)
    • 具体观察者(ConcreteObserver)————订阅者
from abc import ABCMeta, abstractmethod# 订阅者
class Observer(metaclass=ABCMeta):@abstractmethoddef update(self, notice): # notice是一个Notice类的实例pass# 具体订阅者
class Staff(Observer):def __init__(self, name):self.name = nameself.company_info = Nonedef update(self, notice):self.company_info = notice.company_info# 抽象发布者
class Notice:  def __init__(self):self.observers = []def attach(self, observer):self.observers.append(observer)def detach(self, observer):if observer in self.observers:self.observers.remove(observer)# 通知所有订阅者def notify(self):for obs in self.observers:obs.update(self)# 具体发布者
class StaffNotice(Notice):  def __init__(self, company_info=None):super().__init__()self.__company_info = company_info# 访问或更改私有属性@propertydef company_info(self):return self.__company_info@company_info.setterdef company_info(self, new_info):self.__company_info = new_infoself.notify()  # 关键步骤:更新消息后自动通知所有订阅者# obj = StaffNotice("明天放假")
# print(obj.company_info)
# obj.company_info = "后天放假"
# print(obj.company_info)notice = StaffNotice('初始信息')
obj1 = Staff('张三')
obj2 = Staff('李四')notice.attach(obj1)
notice.attach(obj2)notice.company_info = '明天放假'
print(obj1.company_info)
明天放假
  • 适用场景:
    • 当一个抽象模型有两方面,其中一个方面依赖于另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用。
    • 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
    • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
  • 优点:
    • 目标和观察者之间的抽象耦合最小
    • 支持广播通信

策略模式

  • 内容:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
  • 角色:
    • 抽象策略(Strategy)
    • 具体策略(ConcreteStrategy)
    • 多上下文(Context)
from abc import ABCMeta, abstractmethodclass Strategy(metaclass=ABCMeta):@abstractmethoddef execute(self, data):passclass FastStrategy(Strategy):def execute(self, data):print(f"采用快速策略处理{data}")class SlowStrategy(Strategy):def execute(self, data):print(f"采用慢速策略处理{data}")class Context:def __init__(self, strategy, data):self.data = dataself.strategy = strategydef set_strategy(self, strategy):self.strategy = strategydef do_strategy(self):self.strategy.execute(self.data)# 客户端
data = 'data...'
s1 = FastStrategy()
context = Context(s1, data)
context.do_strategy()s2 = SlowStrategy()
context.set_strategy(s2)
context.do_strategy()
采用快速策略处理data...
采用慢速策略处理data...
  • 优点:
    • 定义了一系列可重用的算法和行为
    • 消除了一些条件语句
    • 可以提供相同行为的不同实现
  • 缺点:
    • 多客户必须了解不同的策略

模板方法模式

  • 内容:定义一个操作中的算法的骨架,而将一些步聚延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
  • 角色
    • 抽象类(AbstractClass):定义抽象的原子操作(钩子操作);实现一个模板方法作为算法的骨架。
    • 具体类(ConcreteClass):实现原子操作
from abc import ABCMeta, abstractmethod
from time import sleepclass Window(metaclass=ABCMeta):@abstractmethoddef start(self):pass@abstractmethoddef repaint(self):pass@abstractmethoddef stop(self):  # 原子操作/钩子操作passdef run(self):  # 模板方法self.start()while True:try:self.repaint()sleep(1)except KeyboardInterrupt:print('终止')breakself.stop()class MyWindow(Window):def __init__(self, msg):self.msg = msgdef start(self):print('窗口开始运行')def repaint(self):print(self.msg)def stop(self):print('窗口停止运行')MyWindow('Hello, World!').run()
窗口开始运行
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
终止
窗口停止运行
  • 适用场景:
    • 一次性实现一个算法的不变的部分
    • 各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复
    • 控制子类扩展

http://www.ppmy.cn/news/382096.html

相关文章

技嘉GA7PESH3主板,官网驱动下载,官方使用说明

主板如图 驱动下载 服务器主板驱动比较难找&#xff0c;这里给出官网地址 http://b2b.gigabyte.com/products/product-page.aspx?pid4468#dl 用户手册 也在那个地址&#xff0c;选择一下就好了 https://download.gigabyte.com/FileList/Manual/server_manual_7pesh3_sc_100…

第14届蓝桥杯Scratch(中级)省赛真题解析2023.5.14

选择题 1. 已知下图角色一共有3个造型,则以下选项中,不能呈现下图中第三个造型效果的程序是(C) *选择题严禁使用程序验证,选择题不答或答错都不扣分 A. B. C. D. 2. 运行以下程序,循环执行4次后,x的值是(D)。 *选择题严禁使用程序验证,选择题不答或答错都不扣分

java基础(多线程)-变量的线程安全分析

一、变量的线程安全分析 1.1 成员变量和静态变量是否线程安全 如果他们没有共享&#xff0c;则线程安全如果他们被共享了&#xff0c;根据他们的状态是否能够改变&#xff0c;有份两种情况 如果只有读操作&#xff0c;则线程安全如果有读写操作&#xff0c;则这段代码是临界…

【链表复习】C++ 链表复习及题目解析 (2)

目录 牛客 CM11 链表分割 牛客 OR36 之链表的回文结构 Leetcode 160. 相交链表 LeetCode 141. 环形链表 LeetCode 138. 复制带随机指针的链表 本文继续延续前文&#xff0c;为大家带来几道经典的链表中等难度的题目。 牛客 CM11 链表分割 现有一链表的头指针 ListNode* p…

方太jcd7和jcd9a哪个好真假鉴别,优缺点评测感受

方太jcd7和jcd9a哪个好真假鉴别,优缺点评测感受易清洁&#xff0c;挥手即用&#xff0c;极其方便。安装师傅态度好、技术好&#xff0c;非常感谢&#xff01; 物流很快&#xff0c;第一天下单&#xff0c;第二天就到&#xff0c;师傅安装很好&#xff0c;玻璃面板&#xff0c;高…

老板太难伺候了,能否跳槽换一个好一点的老板?

又到了金三银四的季节&#xff0c;很多年轻人又忙着跳槽了~ 这不&#xff0c;有不少学员私信给我&#xff0c;说他们目前的Java基础太薄弱&#xff0c;工资太低&#xff0c;想要再找一份&#xff0c;问什么时间跳槽最好&#xff1f; 老板太难伺候了&#xff0c;能否跳槽换一个…

老板比员工强的原因

&#xff0c;这是天经地义的事情。要不&#xff0c;他怎么就做了老板&#xff0c;而我等就只能做部下呢&#xff1f; 但很多时候&#xff0c;你会发现&#xff0c;老板在各个方面都比你强&#xff0c;这就值得思辨了&#xff1a;老板为什么啥都比你强&#xff1f;什么样的企业…

微软电脑管家和联想电脑管家哪个好

微软电脑管家和联想电脑管家这两个软件各有优缺点&#xff0c;很难一概而论哪个更好&#xff0c;取决于个人需求和偏好。 微软电脑管家是微软公司出品的安全软件&#xff0c;功能比较全面&#xff0c;包括病毒查杀、漏洞修复、系统清理等多种功能&#xff0c;可以有效保护电脑安…