模板方法模式
"""
案例:写简历
内容:
最近有个招聘会,可以带上简历去应聘了。
但是,其中有一家公司不接受简历,
而是给应聘者发了两张公司自己定制的简历表,分别是A类型的简历表和B类型的简历表
这两张表上面都有差不多的内容:基本信息、教育背景、工作经历,
让应聘者选择其中一种类型的简历表,按照要求填写完整。
每个人拿到这份表格后,就开始填写。
如果用程序实现这个过程,该如何做呢?
一种方案就是用模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
"""
from abc import ABC, abstractmethod
class ResumeTable(ABC):
@abstractmethod
def _write_basic_info(self):
pass
@abstractmethod
def _write_education(self):
pass
@abstractmethod
def _write_work_experience(self):
pass
def 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
@abstractmethod
def execute_command(self):
pass
@abstractmethod
def cancel_command(self):
pass
class AboutMealsCommand(Command):
def __init__(self, chef: Chef):
super().__init__()
self.__chef = chef
def 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 = chef
def 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 = command
def 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
@abstractmethod
def 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 = 3
print(f"我:想要请假{day}天")
group_leader.handle_request(day)
print("-----------------------")
day = 7
print(f"我:想要请假{day}天")
group_leader.handle_request(day)
print("-----------------------")
day = 10
print(f"我:想要请假{day}天")
group_leader.handle_request(day)
print("-----------------------")
day = 30
print(f"我:想要请假{day}天")
group_leader.handle_request(day)
print("-----------------------")
策略模式
from abc import ABC, abstractmethod
class Strategy(ABC):
@abstractmethod
def 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 = strategy
def 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)
break
left = 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 = plan
self._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
@property
def name(self):
return self._place_name
@abstractmethod
def 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):
@abstractmethod
def 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 = None
self._student = None
def set_hr(self, hr):
self._hr = hr
def set_student(self, student):
self._student = student
@abstractmethod
def match(self):
pass
class Role(ABC):
def __init__(self, name: str, offer: str, mediator: Mediator):
self._name = name
self._offer = offer
self._mediator = mediator
@property
def name(self):
return self._name
@property
def offer(self):
return self._offer
@abstractmethod
def 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 = blood
self.__attack = attack
self.__defense = defense
@property
def blood(self):
return self.__blood
@property
def attack(self):
return self.__attack
@property
def defense(self):
return self.__defense
class GameRole:
def __init__(self, ):
self.__blood = 100
self.__attack = 100
self.__defense = 100
def show_state(self):
print(f"当前角色:[生命力:{self.__blood}] [攻击力:{self.__attack}] [防御力:{self.__defense}]")
def fight(self):
self.__blood -= 40
self.__attack -= 16
self.__defense -= 32
print("遭受敌人攻击!生命力-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.blood
self.__attack = memorandum.attack
self.__defense = memorandum.defense
print("恢复存档成功")
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):
@abstractmethod
def 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_state
if __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 self
def __next__(self):
if self.__index < len(self.__lst):
element = self.__lst[self.__index]
self.__index += 1
return element
else:
raise StopIteration
if __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):
@abstractmethod
def 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
@property
def left(self):
return self._left
@property
def right(self):
return self._right
@abstractmethod
def 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 = 0
while i < len(expression):
match expression[i]:
case "@":
left = interpreter_stack.pop()
right = VarInterpreter(expression[i + 1])
interpreter_stack.append(AddInterpreter(left, right))
i += 1
case "#":
left = interpreter_stack.pop()
right = VarInterpreter(expression[i + 1])
interpreter_stack.append(SubInterpreter(left, right))
i += 1
case _:
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 res
if __name__ == '__main__':
expression = "a@b#c"
var_map = {
"a": 30,
"b": 20,
"c": 25
}
parser = Parser(expression)
res = parser.execute(var_map)
print(res)