首页 > 其他分享 >5.行为型模式

5.行为型模式

时间:2024-03-26 21:44:50浏览次数:20  
标签:info data company 模式 strategy 行为 self def

@

目录

1. 责任链模式

       责任链模式的内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链并沿着这条链传递该请求,直到有一个对象处理它为止。责任链的角色有抽象处理者、具体处理者和客户端。

from abc import ABCMeta, abstractmethod

# 抽象的处理者
class Handler(metaclass=ABCMeta):
    @abstractmethod
    def handle_leave(self, day):
        pass

# 具体的处理者
class GeneralManager(Handler):
    def handle_leave(self, day):
        if day <= 30:
            print('总经理准假%d' % day)
        else:
            print('可以辞职了!')

# 具体的处理者
class DepartmentManager(Handler):
    def __init__(self):
        self.next = GeneralManager()

    def handle_leave(self, day):
        if day <= 7:
            print('项目主管准假%d' % 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('项目主管准假%d' % day)
        else:
            print('项目主管职权不足')
            self.next.handle_leave(day)

day = 20
p = ProjectDirector()
p.handle_leave(day)
"""
项目主管职权不足
部门经理职权不足
总经理准假20
"""

       使用场景:有多个对象可以处理一个请求,哪个对象处理由运行时决定;在不明确接收者的情况下,向多个对象中的一个提交一个请求。优点是降低耦合度,一个对象无需知道是其它哪一个对象处理其请求。

2. 观察者模式

       观察者模式应用比较广泛,又被称为“发布-订阅”模式。它用来定义对象间一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。观察者模式的角色有:抽象主题、具体主题(发布者)、抽象观察者和具体观察者(订阅者)。

from abc import ABCMeta, abstractmethod

# 抽象的订阅者
class Observer(metaclass=ABCMeta):
    @abstractmethod
    def update(self, notice):
        """
        :param notice: Notice类的对象
        :return:
        """
        pass

# 抽象的发布者:可以是接口,子类不需要实现,所以不需要定义抽象方法!
class Notice:
    def __init__(self):
        self.observers = []

    def attach(self, obs):
        self.observers.append(obs)

    def detach(self, obs):
        self.observers.remove(obs)

    def notify(self):
        """
        推送
        :return:
        """
        for obs in self.observers:
            obs.update(self)

# 具体的发布者
class StaffNotice(Notice):
    def __init__(self, company_info):
        super().__init__()  # 调用父类对象声明observers属性
        self.__company_info = company_info

    @property
    def company_info(self):
        return self.__company_info

    @company_info.setter
    def company_info(self, info):
        self.__company_info = info
        self.notify()

# 具体的订阅者
class Staff(Observer):
    def __init__(self):
        self.company_info = None

    def update(self, notice):
        self.company_info = notice.company_info

staff_notice = StaffNotice('初始化公司信息')
staff1 = Staff()
staff2 = Staff()
staff_notice.attach(staff1)
staff_notice.attach(staff2)
# print(staff1.company_info) None
# print(staff2.company_info) None
staff_notice.company_info = '假期放假通知!'
print(staff1.company_info)
print(staff2.company_info)
staff_notice.detach(staff2)
staff_notice.company_info = '明天开会!'
print(staff1.company_info)
print(staff2.company_info)
"""
假期放假通知!
假期放假通知!
明天开会!
假期放假通知!
"""

       使用场景:当一个抽象模型有两个方面,其中一个方面依赖另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用;当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象待改变;当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧耦合的。优点:目标和观察者之间的抽象耦合最小;支持广播通信。

3. 策略模式

       定义一个个算法,把它们封装起来,并且使它们可以相互替换。本模式使得算法可独立于使用它的客户而变化。角色有:抽象策略、具体策略和上下文。

from abc import abstractmethod, ABCMeta
from datetime import datetime

# 抽象策略
class Strategy(metaclass=ABCMeta):
    @abstractmethod
    def execute(self, data):
        pass

# 具体策略
class FastStrategy(Strategy):
    def execute(self, data):
        print("使用较快的策略处理%s" % data)

# 具体策略
class SlowStrategy(Strategy):
    def execute(self, data):
        print("使用较慢的策略处理%s" % data)

# 上下文
class Context:
    def __init__(self, strategy, data):
        self.data = data
        self.strategy = strategy
        # 可以定义用户不知道的东西
        self.date = datetime.now()

    def set_strategy(self, strategy):
        self.strategy = strategy

    def do_strategy(self):
        self.strategy.execute(self.data)

data = "Hello!"
# 使用较快的策略处理
fast_strategy = FastStrategy()
context = Context(fast_strategy, data)
context.do_strategy()
# 使用较慢的策略处理
slow_strategy = SlowStrategy()
context = Context(slow_strategy, data)
context.do_strategy()
"""
使用较快的策略处理Hello!
使用较慢的策略处理Hello!
"""

       优点:定义了一些列可重用的算法和行为;消除了一些条件语句;可以提供相同行为的不同实现;缺点:客户必须了解不同的策略。

4. 模板方法模式

       内容:定义一个操作中的算法骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。使用模板方法,需要用到两种角色,分别是抽象类和具体类。抽象类的作用是是定义抽象类(钩子操作),实现一个模板方法作为算法的骨架。具体类的作用实现原子操作。

from abc import ABCMeta, abstractmethod
from time import sleep

# 抽象类
class Window(metaclass=ABCMeta):
    @abstractmethod
    def start(self):  # 原子操作/钩子操作
        pass

    @abstractmethod
    def repaint(self):  # 原子操作/钩子操作
        pass

    @abstractmethod
    def stop(self):  # 原子操作/钩子操作
        pass

    def run(self):
        """
        模板方法(具体方法),这个大逻辑就不需要自己写了
        :return:
        """
        self.start()
        while True:
            try:
                self.repaint()
                sleep(1)
            except KeyboardInterrupt:
                break
        self.stop()

# 具体类
class MyWindow(Window):
    def __init__(self, msg):
        self.msg = msg

    def start(self):
        print('窗口开始运行!')

    def stop(self):
        print('窗口停止运行!')

    def repaint(self):
        print(self.msg)

MyWindow("Hello...").run()

       模板方法适用的场景:一次性实现一个算法的不变部分,各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复;控制子类扩展。

标签:info,data,company,模式,strategy,行为,self,def
From: https://www.cnblogs.com/thankcat/p/18097666

相关文章

  • 4.结构型模式
    @目录1.适配器模式2.桥模式3.组合模式4.外观模式5.代理模式1.适配器模式      将一个类的接口转换成客户希望的另外一个接口,适配器使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。实现适配器的两种方式,类适配器使用多继承,对象适配器使用组合。组合就......
  • 工厂模式
     1.工厂模式介绍提供了一种将对象创建过程封装到一个单独的类中的方式,这个类就是被称为‘工厂类’,它根据特定的条件来决定应该创建哪个对象 2.工厂模式的创建方式(1)简单工厂模式publicinterfacePhone{/***抽象电话功能*/voidcall()......
  • Blazor学习记录六_模版化组件_渲染模式_CSS隔离和代码隔离
    17.模版化组件在组件中放置一个可渲染的代码片段供外部调用者来传入要渲染的内容及渲染样式,这样的组件就叫做模版化的组件。一般是一个支持泛型的组件,目标为消费者封装重复使用的通用性良好的UI组件。比如一个用来给用户呈现表格数据的表格组件。示例组件GenaricTable.razor代......
  • Redis发布订阅模式解决Guava Cache本地缓存刷新问题
    为什么要用本地缓存可以加快资源访问速度,减少第三方IO延迟,也避免了网络调用的开销,将数据存储在本地jvm内存中可以减少外部系统的压力,可以将频繁访问、且更新场景较少的数据缓存起来,降低对远程服务或者数据库的请求次数,降低外部系统负载,提供系统整体的稳定性缺点:但是同时也得......
  • Windows Packet Divert(WinDivert)是一个适用于Windows 10、Windows 11和Windows Server
    WindowsPacketDivert(WinDivert)是一个适用于Windows10、Windows11和WindowsServer的用户模式数据包捕获和重定向工具。WinDivert允许用户模式应用程序捕获/修改/丢弃发送到/从Windows网络堆栈的网络数据包。总之,WinDivert可以:捕获网络数据包过滤/丢弃网络数据包嗅探......
  • [AI][osg]关于osg的options的设计模式
    Options说明OSG(OpenSceneGraph)是一个高性能的开源3D图形工具包,用于可视化仿真、游戏、虚拟现实、科学可视化等领域。它提供了一套丰富的API和工具,帮助开发者创建复杂的3D场景和应用程序。在OSG中,Options机制用于控制场景图读取过程中的各种参数和行为。通过Options,开发者可以指......
  • 前端面试题:hash模式和history模式
    hash(哈希)和history(历史)是前端路由的两种模式,它们的主要区别在url,兼容性,服务器配置,美观性,和导航操作上面1,URLhash的url前面有#来表示路径,而history没有hash:hash模式是一种把前端路由的路径用#拼接在真实url后面的模式,通过hashchange事件监听hash值的改变来渲染页......
  • 训练人形机器人时如何收集人类行为数据 —— 通过人来训练机器人(真人实际演示动作)or
    特斯拉的老马,搞的optimus人形机器人就是通过人来训练机器人(真人实际演示动作),但是未来使用仿真环境自动生成数据是否可行呢,NVIDIA的老黄在2024GTC上是大力推出自家的GROOT平台,该平台的主要数据则是使用仿真器生成的,到底哪种方式更优呢?......
  • 如何杜绝员工工作时间的不当行为,确保数据保密性?
    当代公司面临的一个重要问题是许多员工在工作时间内进行与工作无关的活动,如社交聊天、购物、炒股、看电影等,这不仅影响了工作效率,也可能会导致公司数据的泄露。因此,如何杜绝员工在工作时间的不当行为,确保数据的保密性,成为了每家公司必须解决的问题。以下是关于这个问题的一些解决......
  • 代理模式(静态代理和动态代理)
    1.静态代理    静态代理中代理类与被代理类都需要实现同一个接口,这就说明我们的一个静态代理类只能代理一个类,并且还要事先知道我们要代理哪个类才能写代理类,如果我们有其他类还想使用代理那就必须再写一个代理类。【1】测试案例:法外狂徒张三叫律师打官司packageco......