访问者模式

# -*- 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)  # 处方交由 药房 管理员处理


posted @   染指未来  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示