【设计模式】4.代理模式

发布于:2025-06-22 ⋅ 阅读:(17) ⋅ 点赞:(0)

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

代理模式

20250518094605

1. 第一版

class SchoolGirl:
    def __init__(self):
        self._name = None
    
    @property
    def name(self):
        return self._name
    
    @name.setter
    def name(self, value):
        self._name = value

class Pursuit:
    def __init__(self, mm):
        self.mm = mm
    
    def give_dolls(self):
        print(f"{self.mm.name}送你洋娃娃")
    
    def give_flowers(self):
        print(f"{self.mm.name}送你鲜花")
    
    def give_chocolate(self):
        print(f"{self.mm.name}送你巧克力")

# 客户端调用代码
if __name__ == "__main__":
    jiaojiao = SchoolGirl()
    jiaojiao.name = "李娇娇"
    zhuojiayi = Pursuit(jiaojiao)
    zhuojiayi.give_dolls()
    zhuojiayi.give_flowers()
    zhuojiayi.give_chocolate()
    input()  # 相当于C#的Console.Read()

这一版本没有代理,增加代理

2. 第二版

20250518094740

class SchoolGirl:
    def __init__(self):
        self._name = None
    
    @property
    def name(self):
        return self._name
    
    @name.setter
    def name(self, value):
        self._name = value

class Proxy:
    def __init__(self, mm):
        self.mm = mm
    
    def give_dolls(self):
        print(f"{self.mm.name} 送你洋娃娃")
    
    def give_flowers(self):
        print(f"{self.mm.name} 送你鲜花")
    
    def give_chocolate(self):
        print(f"{self.mm.name} 送你巧克力")

# 客户端调用代码
if __name__ == "__main__":
    jiaojiao = SchoolGirl()
    jiaojiao.name = "李娇娇"
    daili = Proxy(jiaojiao)
    daili.give_dolls()
    daili.give_flowers()
    daili.give_chocolate()
    input()  # 等待用户输入,相当于C#的Console.Read()

3. 第三版

20250518095309

以下是完整的 Python 实现,包含接口抽象、追求者类、代理类和客户端代码,严格遵循代理模式的设计:

from abc import ABC, abstractmethod

# 代理接口 (Python 中使用抽象基类实现接口)
class GiveGift(ABC):
    @abstractmethod
    def give_dolls(self):
        pass
    
    @abstractmethod
    def give_flowers(self):
        pass
    
    @abstractmethod
    def give_chocolate(self):
        pass

# SchoolGirl 类
class SchoolGirl:
    def __init__(self):
        self._name = None
    
    @property
    def name(self):
        return self._name
    
    @name.setter
    def name(self, value):
        self._name = value

# 追求者类 (实现 GiveGift 接口)
class Pursuit(GiveGift):
    def __init__(self, mm):
        self.mm = mm
    
    def give_dolls(self):
        print(f"{self.mm.name} 送你洋娃娃")
    
    def give_flowers(self):
        print(f"{self.mm.name} 送你鲜花")
    
    def give_chocolate(self):
        print(f"{self.mm.name} 送你巧克力")

# 代理类 (同样实现 GiveGift 接口)
class Proxy(GiveGift):
    def __init__(self, mm):
        self.gg = Pursuit(mm)  # 内部持有追求者实例
    
    def give_dolls(self):
        self.gg.give_dolls()  # 调用追求者的方法
    
    def give_flowers(self):
        self.gg.give_flowers()
    
    def give_chocolate(self):
        self.gg.give_chocolate()

# 客户端代码
if __name__ == "__main__":
    jiaojiao = SchoolGirl()
    jiaojiao.name = "李娇娇"
    
    # 使用代理而不是直接使用追求者
    daili = Proxy(jiaojiao)
    daili.give_dolls()
    daili.give_flowers()
    daili.give_chocolate()
    
    input()  # 等待用户输入

关键设计说明:

  1. 使用 abc 模块实现了 GiveGift 接口(Python 没有原生接口,用抽象基类模拟)
  2. PursuitProxy 都继承自 GiveGift,保证接口一致性
  3. Proxy 内部持有 Pursuit 实例,所有方法调用都委托给实际追求者
  4. 客户端只与代理交互,不知道实际追求者的存在
  5. 保持了原始设计中的所有核心关系和方法调用流程

这个实现完整展示了代理模式的几个关键特点:

  • 为其他对象提供一种代理以控制对这个对象的访问
  • 代理类和真实类实现相同接口
  • 代理类内部持有真实类的实例
  • 客户端通过代理间接访问真实对象