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