every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog
0. 前言
代理模式
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. 第二版
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. 第三版
以下是完整的 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() # 等待用户输入
关键设计说明:
- 使用
abc
模块实现了GiveGift
接口(Python 没有原生接口,用抽象基类模拟) Pursuit
和Proxy
都继承自GiveGift
,保证接口一致性Proxy
内部持有Pursuit
实例,所有方法调用都委托给实际追求者- 客户端只与代理交互,不知道实际追求者的存在
- 保持了原始设计中的所有核心关系和方法调用流程
这个实现完整展示了代理模式的几个关键特点:
- 为其他对象提供一种代理以控制对这个对象的访问
- 代理类和真实类实现相同接口
- 代理类内部持有真实类的实例
- 客户端通过代理间接访问真实对象