模板方法模式
"""案例:写简历内容:最近有个招聘会,可以带上简历去应聘了。但是,其中有一家公司不接受简历,而是给应聘者发了两张公司自己定制的简历表,分别是A类型的简历表和B类型的简历表这两张表上面都有差不多的内容:基本信息、教育背景、工作经历,让应聘者选择其中一种类型的简历表,按照要求填写完整。每个人拿到这份表格后,就开始填写。如果用程序实现这个过程,该如何做呢?一种方案就是用模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
"""from abc import ABC, abstractmethod
class ResumeTable(ABC):@abstractmethoddef _write_basic_info(self): pass@abstractmethoddef _write_education(self): pass@abstractmethoddef _write_work_experience(self): passdef fill_resume(self):self._write_basic_info() self._write_education() self._write_work_experience()
class ResumeTableA(ResumeTable):def _write_basic_info(self):print("简历A: 基本信息, ", end="")def _write_education(self):print("教育背景, ", end="")def _write_work_experience(self):print("工作经验 (越简单越好).")
class ResumeTableB(ResumeTable):def _write_basic_info(self):print("简历B: 基本信息, ", end="")def _write_education(self):print("教育背景, ", end="")def _write_work_experience(self):print("工作经验 (越详细越好).")if __name__ == '__main__':a = ResumeTableA()a.fill_resume()b = ResumeTableB()b.fill_resume()
命令模式
"""案例:客人点餐1. 客人发出命令,让厨师做饭2. 客人发出命令,让厨师取消做饭3. 客人发出命令,让厨师煮面4. 客人发出命令,让厨师取消煮面
"""from abc import ABC, abstractmethod
class Chef: def make_meals(self):print("做饭")def cancel_meals(self):print("取消做饭")def make_noodles(self):print("煮面")def cancel_noodles(self):print("取消煮面")
class Command(ABC):def __init__(self):self.__chef = None @abstractmethoddef execute_command(self): pass@abstractmethoddef cancel_command(self): pass
class AboutMealsCommand(Command):def __init__(self, chef: Chef):super().__init__()self.__chef = chefdef execute_command(self):print("快点去给我", end="")self.__chef.make_meals()def cancel_command(self):print("我不要了,", end="")self.__chef.cancel_meals()
class AboutNoodlesCommand(Command):def __init__(self, chef: Chef):super().__init__()self.__chef = chefdef execute_command(self):print("快点去给我", end="")self.__chef.make_noodles()def cancel_command(self):print("我不要了,", end="")self.__chef.cancel_noodles()
class Customer:def think_command(self, command: Command):self.__command = commanddef speak_to_eat(self):self.__command.execute_command()def speak_to_cancel(self):self.__command.cancel_command()if __name__ == '__main__':chef = Chef()about_meals_command = AboutMealsCommand(chef)about_noodles_command = AboutNoodlesCommand(chef)customer = Customer()customer.think_command(about_meals_command)customer.speak_to_eat() customer.speak_to_cancel() customer.think_command(about_noodles_command)customer.speak_to_eat() """
运行结果:快点去给我做饭我不要了,取消做饭快点去给我煮面
"""
责任链模式
"""案例:员工请假内容:当员工申请请假1天以内,由组长批准即可(处理者为组长)当员工申请请假超过3天,需要由经理批准(处理者为经理)当员工申请请假超过7天,需要由老板批准(处理者为老板)
"""from abc import ABC, abstractmethod
class Handler(ABC):def __init__(self):self._next_handler = None def set_next_handler(self, next_handler):self._next_handler = next_handler@abstractmethoddef handle_request(self, days):pass
class GroupLeader(Handler):def handle_request(self, days: int):print("组长:", end="")if days <= 3:print("同意请假!")else:print("请假太久了,你去找经理请假。")if self._next_handler:self._next_handler.handle_request(days)
class Manager(Handler):def handle_request(self, days: int):print("经理:", end="")if days <= 7:print("同意请假!")else:print("请假太久了,你去找老板请假。")if self._next_handler:self._next_handler.handle_request(days)
class Boss(Handler):def handle_request(self, days: int):print("老板:", end="")if days <= 10:print("同意请假!")else:print("请假太久了,不同意请假")if self._next_handler:self._next_handler.handle_request(days)if __name__ == '__main__':group_leader = GroupLeader()manager = Manager()boss = Boss()group_leader.set_next_handler(manager)manager.set_next_handler(boss)day = 3print(f"我:想要请假{day}天")group_leader.handle_request(day)print("-----------------------")day = 7print(f"我:想要请假{day}天")group_leader.handle_request(day)print("-----------------------")day = 10print(f"我:想要请假{day}天")group_leader.handle_request(day)print("-----------------------")day = 30print(f"我:想要请假{day}天")group_leader.handle_request(day)print("-----------------------")
策略模式
from abc import ABC, abstractmethod
class Strategy(ABC):@abstractmethoddef execute(self, left: int, right: int): pass
class AddStrategy(Strategy):def execute(self, left: int, right: int):return left + right
class SubStrategy(Strategy):def execute(self, left: int, right: int):return left - right
class MulStrategy(Strategy):def execute(self, left: int, right: int):return left * right
class DivStrategy(Strategy):def execute(self, left: int, right: int):if right == 0:raise "除数不能为零!"return left / right
class Container:def __init__(self):self.__strategy = None def set_strategy(self, strategy: Strategy):self.__strategy = strategydef execute_strategy(self, left: int, right: int):return self.__strategy.execute(left, right)if __name__ == '__main__':container = Container()symbol_list = ("+", "-", "*", "/") index = 0 while True:expression = input("(Count) >>> ")for symbol in symbol_list:if symbol in expression: index = expression.index(symbol) breakleft = int(expression[0: index: 1].strip())right = int(expression[index + 1: len(expression): 1].strip())match expression[index]:case "+":container.set_strategy(AddStrategy()) case "-":container.set_strategy(SubStrategy()) case "*":container.set_strategy(MulStrategy()) case "/":container.set_strategy(DivStrategy()) case _:raise "符号错误!"print(container.execute_strategy(left, right))
观察者模式
"""
案例:员工摸鱼
通过老板的动作信息(是否出现在公司),员工做出不同的反应(摸鱼或努力工作)
"""from abc import ABC, abstractmethod
class Employee:def __init__(self, name):self.__name = name def update(self, info):print(f"{self.__name}收到情报:{info},", end="")if info == "老板来了":print("开启工作模式。")elif info == "老板走了":print("开启摸鱼模式。")
class Boss:def __init__(self):self.__employee_list = [] self.__action_plan = "" def add_employee(self, employee: Employee):self.__employee_list.append(employee)def set_action_plan(self, plan):self.__action_plan = planself._notify(plan) def _notify(self, plan):info = ""if plan == "去巡查一下他们有没有好好工作":info = "老板来了"elif plan == "坐飞机出个差":info = "老板走了"for employee in self.__employee_list:employee.update(info)if __name__ == '__main__':boss = Boss()emp_1 = Employee("小明")emp_2 = Employee("老张")emp_3 = Employee("老李")boss.add_employee(emp_1)boss.add_employee(emp_2)boss.add_employee(emp_3)boss.set_action_plan("去巡查一下他们有没有好好工作")print("-----------")boss.set_action_plan("坐飞机出个差")print("-----------")
访问者模式
"""案例:这里实现一个不同职业的人去医院和餐厅的例子来说明访问者模式在小镇上有一个医院和一个餐厅,每天都会有不同的人访问这两个地方,由于访问者不同到这两个地方要做的事也有区别。医生去医院是为了工作给病人看病,厨师去医院是为了检查身体,医生去餐厅是为了吃饭,厨师去餐厅是为了工作给客人烹饪菜肴。
"""from abc import ABC, abstractmethod
class Place(ABC):def __init__(self, name: str):self._place_name = name @propertydef name(self):return self._place_name@abstractmethoddef accept(self, visitor): pass
class Hospital(Place):def accept(self, visitor):if visitor.__class__ is Doctor:print(f"医院热情的接待他,因为他能帮助医院救人!")elif visitor.__class__ is Chef:print("医院快速的接待他,因为他来看病!")
class Restaurant(Place):def accept(self, visitor):if visitor.__class__ is Doctor:print(f"餐厅热情的接待他,因为他是顾客!")elif visitor.__class__ is Chef:print("餐厅快速的接待他,因为他要炒菜!")
class Visitor(ABC):@abstractmethoddef visit(self, place): pass
class Doctor(Visitor):def visit(self, place):print(f"医生尝试访问{place.name},", end="")place.accept(self)
class Chef(Visitor):def visit(self, place):print(f"厨师尝试访问{place.name},", end="")place.accept(self) if __name__ == '__main__':hospital = Hospital("蟒蛇市第一人民医院")restaurant = Restaurant("幸福餐馆")doctor = Doctor()chef = Chef()doctor.visit(hospital) doctor.visit(restaurant) chef.visit(hospital) chef.visit(restaurant) """
运行结果:医生尝试访问蟒蛇市第一人民医院,医院热情的接待他,因为他能帮助医院救人!医生尝试访问幸福餐馆,餐厅热情的接待他,因为他是顾客!厨师尝试访问蟒蛇市第一人民医院,医院快速的接待他,因为他来看病!厨师尝试访问幸福餐馆,餐厅快速的接待他,因为他要炒菜!
"""
中介者模式
from abc import ABC, abstractmethod
class Mediator(ABC):def __init__(self):self._hr = Noneself._student = Nonedef set_hr(self, hr):self._hr = hrdef set_student(self, student):self._student = student@abstractmethoddef match(self):pass
class Role(ABC):def __init__(self, name: str, offer: str, mediator: Mediator):self._name = nameself._offer = offerself._mediator = mediator@propertydef name(self):return self._name@propertydef offer(self):return self._offer@abstractmethoddef match(self, role): pass
class Student(Role):def match(self, role):self._mediator.set_student(self) self._mediator.set_hr(role) self._mediator.match()
class HR(Role):def match(self, role):self._mediator.set_hr(self) self._mediator.set_student(role) self._mediator.match()
class LiePinApp(Mediator):def match(self):print("--------------- 欢迎使用猎聘App ---------------")print(f"HR:{self._hr.name}\t|\t想要招聘:{self._hr.offer}")print(f"学生:{self._student.name}\t|\t想要应聘:{self._student.offer}")if self._hr.offer == self._student.offer:print(">>> 配对成功")else:print(">>> 配对失败")print("---------------------------------------------", end="\n\n")if __name__ == '__main__':app = LiePinApp()hr = HR("花儿姐", "软件工程师", app)stu_1 = Student("小明", "软件工程师", app)stu_2 = Student("小王", "硬件工程师", app)hr.match(stu_1)hr.match(stu_2)
备忘录模式
"""备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。案例:比如我们打游戏时分,如果在打大BOSS之前存档,此时就需要将对应的游戏场景,任务信息,人物信息等等状态存储起来;当赢得大BOSS之后,覆盖之前的存档时,就将之前的存档丢弃,新建立一个存档,保存当前的状态信息;如果打输了,恢复存档,就将之前的存档信息读取出来,还原到打大BOSS之前的游戏场景,重新开始打大BOSS。这里面就是使用的备忘录模式。一个备忘录是一个对象,它存储另一个对象在某个瞬间的内部状态,而后者称为备忘录的原发器。当需要设置原发器的检查点时,取消操作机制会向原发器请求一个备忘录。原发器用描述当前状态的信息初始化该备忘录。只有原发器可以向备忘录中存取信息,备忘录中的信息对其他的对象是“不可见”的。
"""
from abc import ABC, abstractmethod
class Memorandum:def __init__(self, blood, attack, defense):self.__blood = bloodself.__attack = attackself.__defense = defense@propertydef blood(self):return self.__blood@propertydef attack(self):return self.__attack@propertydef defense(self):return self.__defense
class GameRole:def __init__(self, ):self.__blood = 100self.__attack = 100self.__defense = 100def show_state(self):print(f"当前角色:[生命力:{self.__blood}] [攻击力:{self.__attack}] [防御力:{self.__defense}]")def fight(self):self.__blood -= 40self.__attack -= 16self.__defense -= 32print("遭受敌人攻击!生命力-40,攻击力-16,防御力-32...")if self.__blood <= 0:print("您已阵亡!")def save_state(self):print("存档成功!")return Memorandum(self.__blood, self.__attack, self.__defense)def recovery_state(self, memorandum: Memorandum):self.__blood = memorandum.bloodself.__attack = memorandum.attackself.__defense = memorandum.defenseprint("恢复存档成功")if __name__ == '__main__':role = GameRole()role.show_state()role.fight()record = role.save_state()role.fight()role.fight()role.recovery_state(record)role.fight()
状态模式
from abc import ABC, abstractmethod
class State(ABC):@abstractmethoddef handle(self):pass
class NoneState(State):def handle(self):return "没有上下文..."
class ExistState(State):def handle(self):return "存在上下文..."
class Context:def __init__(self, state: State):self.__state = state def request(self):if self.__state:print(f"内容:[{self.__state.handle()}]")def change_state(self, new_state):self.__state = new_stateif __name__ == '__main__':none_state = NoneState()exist_state = ExistState()context = Context(none_state)context.request()context.change_state(exist_state)context.request()
迭代器模式
from abc import ABC, abstractmethod
class SimpleIterator:def __init__(self, lst):self.__lst = lst self.__index = 0 def __iter__(self):return selfdef __next__(self):if self.__index < len(self.__lst): element = self.__lst[self.__index]self.__index += 1return elementelse: raise StopIterationif __name__ == '__main__':my_list = [5, 4, 3, 2, 1]my_iter = SimpleIterator(my_list)try:while True:print(next(my_iter))except StopIteration:pass
解释器模式
"""实现原理:原材料:1.表达式(计算规则): a@b#c (需要解释成a+b-c的运算过程和结果)2.数据对应关系(变量):var_map = {"a": 30,"b": 20,"c": 25}产品:a@b#c ==》 变量解释器1 @ 变量解释器2 # 变量解释器3==》 栈 【 => 变量解释器1 => 变量解释器2 => 变量解释器3 => 】 与 【=> @符号对象 => #符号对象】
"""from abc import ABC, abstractmethod
class Interpreter(ABC):@abstractmethoddef parse(self, var_map: dict): pass
class VarInterpreter(Interpreter):def __init__(self, var: str):self.__var = var def parse(self, var_map: dict) -> int: return var_map[self.__var]
class SymbolInterpreter(Interpreter):def __init__(self, left: VarInterpreter, right: VarInterpreter):self._left = left self._right = right @propertydef left(self): return self._left@propertydef right(self): return self._right@abstractmethoddef parse(self, var_map: dict):pass
class AddInterpreter(SymbolInterpreter):def parse(self, var_map: dict) -> int:return self._left.parse(var_map) + self._right.parse(var_map)
class SubInterpreter(SymbolInterpreter):def parse(self, var_map: dict) -> int:return self._left.parse(var_map) - self._right.parse(var_map)
class Parser:def __init__(self, expression: str):self.__final_interpreter = None interpreter_stack = [] i = 0while i < len(expression):match expression[i]:case "@": left = interpreter_stack.pop()right = VarInterpreter(expression[i + 1])interpreter_stack.append(AddInterpreter(left, right))i += 1case "#": left = interpreter_stack.pop()right = VarInterpreter(expression[i + 1])interpreter_stack.append(SubInterpreter(left, right))i += 1case _:interpreter_stack.append(VarInterpreter(expression[i]))i += 1 if interpreter_stack: self.__final_interpreter = interpreter_stack.pop() def execute(self, var_map: dict) -> int:res = -1 if (self.__final_interpreter is None) else self.__final_interpreter.parse(var_map)return resif __name__ == '__main__':expression = "a@b#c"var_map = {"a": 30,"b": 20,"c": 25}parser = Parser(expression)res = parser.execute(var_map) print(res)