python设计模式-行为型模式

责任链模式

责任链模式 – 用于让多个对象处理一个请求时,或者用于预先不知道由哪个对象来处理某种特定请求时,其原则如下:

1、存在一个对象链(链表、树或者其他便捷的数据结构)。

2、一开始将请求发送给第一个对象,让其处理。

3、对象决定是否处理该请求。

4、对象将请求转发给下一个对象。

5、重复该过程,直到达到链尾。

  • 优点

    • 将请求者与处理者分离,请求者并不知道请求是被哪个处理者所处理,易于扩展。
  • 缺点

    • 如果责任链比较长,会有比较大的性能问题;
    • 如果责任链比较长,若业务出现问题,比较难定位是哪个处理者的问题。
  • 应用场景

    • 若一个请求可能由一个对请求有链式优先级的处理群所处理时,可以考虑责任链模式。
  • 代码示例

    import abc
    
    
    class Leader(abc.ABC):
        """
        领导类
        """
    
        def __init__(self, name, leader=None):
            self.leader = leader
            self.name = name
    
        @abc.abstractmethod
        def handle_request(self, request):
            """
            处理请求
            """
            ...
    
    
    class DepartmentLeader(Leader):
        """
        部门领导
        """
    
        def handle_request(self, request):
            print(f'2.{self.name}正在审批...')
            if request.days <= 3:
                print(f'批准!')
            else:
                if self.leader:
                    print(f'等待上级领导审批!')
                    self.leader.handle_request(request)
    
    
    class Boss(Leader):
        """
        老板
        """
    
        def handle_request(self, request):
            print(f'3.{self.name}审批')
            print(f'批准!')
    
    
    class Request:
        def __init__(self, name, desc, days=0):
            self.name = name
            self.desc = desc
            self.days = days
    
        def commit(self, leader):
            print(f"1.提交申请")
            print(f"姓名:{self.name},请假原因:{self.desc},请假天数:{self.days}")
            ret = leader.handle_request(self)
            return ret
    
    
    if __name__ == "__main__":
        boss = Boss('Boss')
        department_leader = DepartmentLeader('DepartmentLeader', boss)
    
        Request(name='zs', desc="家中有事", days=2).commit(department_leader)
        print("*" * 20)
        Request(name='ls', desc="回家结婚", days=15).commit(department_leader)
    
    
    

命令模式

敬请期待!点击可先学习其他设计模式

解释器模式

敬请期待!点击可先学习其他设计模式

迭代器模式

敬请期待!点击可先学习其他设计模式

中介者模式

敬请期待!点击可先学习其他设计模式

备忘录模式

敬请期待!点击可先学习其他设计模式

观察者模式

敬请期待!点击可先学习其他设计模式

状态模式

敬请期待!点击可先学习其他设计模式

空对象模式

敬请期待!点击可先学习其他设计模式

策略模式

策略模式作为一种软件设计模式,一般我们定义了一组算法(业务规则),算法之间可互换代替(interchangeable)而不会影响到用户使用,以满足用户多样化的需求。

  • 结构

    • Stragety:策略基类, 用于定义所有支持算法的公共接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
    • ConcreteStragety:具体策略,继承于Strategy,具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。
    • Context:上下文环境类, 也叫封装类,对策略进行二次封装,目的是避免高层模块对策略的直接调用。 Context用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用
  • 优点

    • 策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。
    • 易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展。
    • 避免使用多重条件,如果不使用策略模式,对于所有的算法,必须使用条件语句进行连接,通过条件判断来决定使用哪一种算法,在上一篇文章中我们已经提到,使用多重条件判断是非常不容易维护的。
  • 缺点

    • 项目比较庞大时,策略可能比较多,不便于维护;
    • 策略的使用方必须知道有哪些策略,才能决定使用哪一个策略,这与迪米特法则是相违背的。
  • 代码示例

    from abc import ABC, abstractmethod
    
    
    class BaseStrategy(ABC):
        @abstractmethod
        def accept_cash(self, money): ...
    
    
    # 正常付费
    class StrategyNormalUser(BaseStrategy):
    
        def accept_cash(self, money):
            print("正常计费 ", end='')
            return money
    
    
    class StrategyVipUser(BaseStrategy):
        """策略1: 正常收费子类"""
    
        def accept_cash(self, money):
            print("vip计费 ", end='')
            return money * 0.95
    
    
    # 具体策略类
    class ContextOrder(object):
    
        def __init__(self, user):
            self.user = user
    
        def accept_cash(self, money):
            real_money = self.user.accept_cash(money)
            print(f"原件:{money}元,实收:{real_money}元")
            return real_money
    
    
    if __name__ == '__main__':
        strategy1 = StrategyNormalUser()
        strategy2 = StrategyVipUser()
        ContextOrder(strategy1).accept_cash(100)
        ContextOrder(strategy2).accept_cash(100)
    
     
    

模板模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

  • 优点
    • 行为由父类控制,具体实现在子类;
    • 封装不变部分,扩展可变部分。
  • 缺点
    • 每一个实现都需要一个子类,会使类的数量增加。
import abc


# 抽象模板类
class CarBuilder(abc.ABC):

    @abc.abstractmethod
    def build_frame(self): ...

    @abc.abstractmethod
    def build_wheel(self): ...

    @abc.abstractmethod
    def build_engine(self): ...

    def build_car(self):
        """
        通用逻辑,封装每一个步骤
        :return:
        """
        self.build_frame()
        self.build_wheel()
        self.build_engine()


# 具体实现类
class BmwBuilder(CarBuilder):
    def build_frame(self):
        print("装bmw车架")

    def build_wheel(self):
        print("装bmw轮子")

    def build_engine(self):
        print("装bmw发动机")


# 具体实现类
class AudiBuilder(CarBuilder):
    def build_frame(self):
        print("装Audi车架")

    def build_wheel(self):
        print("装Audi轮子")

    def build_engine(self):
        print("装Audi发动机")


if __name__ == '__main__':
    BmwBuilder().build_car()
    AudiBuilder().build_car()

访问者模式

敬请期待!点击可先学习其他设计模式

你可能感兴趣的:(设计模式,设计模式,状态模式)