# -*- coding: utf-8 -*-
#### 访问者模式:
"""
- 定义:
1. 封装 一些 作用于 某种数据结构中的各元素操作
2. 可以在不改变原有数据结构的前提下,定义且作用于这些新元素的操作
3. 双分派: 静态派 和 动态派, 取决于 请求者的名称和接收到的参数
- 场景:
1. 要遍历不同的对象, 根据不同的对象,进行不同的操作
2. 一个对象 被 多个不同对象顺次处理的情况
3. 报表生成器也可以使用 访问者模式来实现,报表数据源由多个不同的对象
- 优点:
1. 将不同职责 明确分开,符合单一职责原则
2. 职责的分开 直接导致 拓展性非常好. 灵活度高,加减元素 和 访问者都非常容易
- 缺点:
1. 访问者的值 元素季节,与最小隔离原则相悖
2. 元素变更 , 可能引起visitor的修改
"""
class Medicine():
name = ''
price = 0.0
def __init__(self, name, price):
self.name = name
self.price = price
def getName(self):
return self.name
def setName(self, name):
self.name = name
def getPrice(self):
return self.price
def setPrice(self, price):
self.price = price
def accpet(self, visitor):
pass
class Antibiotic(Medicine):
"""
# 抗生素药物
"""
def accept(self, visitor):
visitor.visit(self)
class Coldrex(Medicine):
"""
# 感冒药物
"""
def accept(self, visitor):
visitor.visit(self)
class Vistor():
"""
# 访客
"""
name = ''
def setName(self, name):
self.name = name
def visit(self, medicine):
pass
class Charger(Vistor):
"""
# 药品划价员
"""
def visit(self, medicine):
print(f'CHARGE:{self.name} lists the Medicine {medicine.getName()}. Price:{medicine.getPrice()}')
class Pharmacy(Vistor):
"""
# 药房管理员
"""
def visit(self, medicine):
print(f'PHARMACY:{self.name} offers the Medicine {medicine.getName()}. Price:{medicine.getPrice()}')
class ObjectStructure:
pass
class Prescription(ObjectStructure):
"""
Prescription 处方
"""
medicines = []
def addMedicine(self, medicine):
"""
添加药物
:param medicine:
:return:
"""
self.medicines.append(medicine)
def rmvMedicine(self, medicine):
"""
移除药物
:param medicine:
:return:
"""
self.medicines.remove(medicine)
def visit(self, visitor):
"""
# 循环当前处方中的药物
:param visitor:
:return:
"""
for medc in self.medicines:
medc.accept(visitor)
if __name__ == '__main__':
# 1. 药物 信息 创建
yq_pill = Coldrex('YinQiao Pill', 5.0)
penicillin = Antibiotic('penicillin', 15)
doctor_prsrp = Prescription()
# 2. 处方中 添加药物
doctor_prsrp.addMedicine(yq_pill)
doctor_prsrp.addMedicine(penicillin)
# 3. 药品 划价员 , 药房 管理员
charger = Charger()
charger.setName('Doctor Strange')
pharmacy = Pharmacy()
pharmacy.setName('Doctor Wei')
doctor_prsrp.visit(charger) # 处方 交由 药品 划价员处理
doctor_prsrp.visit(pharmacy) # 处方交由 药房 管理员处理