设计模式之代理模式-骆驼与巴巴羊的故事
代理模式
代理模式允许在访问特定对象时添加一些额外行为,主要用于控制对一个对象的访问,提供一个代理或占位符。代理类充当客户端和实际对象之间的中介,但是它和中介者模式截然不同。
客户端通过代理访问实际对象,在访问实际对象时进行额外的处理,如延迟加载、访问控制、日志记录等。
代理模式的角色
- 抽象主题(定义了真实主题和代理主题的公共接口)
- 真实主题(实现抽象主题定义的接口,是实际执行操作的对象)
- 代理主题(实现抽象主题定义的接口,内部持有真实主题对象,以便随时访问)
代理模式的优缺点
优点:
- 控制访问权限:在访问目标对象之前添加身份验证,权限检查逻辑,确保只有授权的客户端才能访问目标对象,提高系统安全性
- 延迟加载:在某些情况下,目标对象创建或加载可能需要较多的资源或时间,代理模式可以通过延迟加载机制,仅在实际需要时才创建或加载目标对象,从而优化资源使用和提高性能。
- 远程访问支持:客户端访问位于远程服务器上的目标对象时,可以通过代理就像访问本地对象一样访问远程对象,简化了开发和使用流程。
- 增加扩展功能:在不修改目标对象的情况下,通过代理对象添加额外功能,比如日志记录,性能监控,缓存等。
缺点:
- 增加系统复杂性
- 性能开销
- 透明度降低,比如洋葱路由
- 额外的开发和维护成本
- 潜在的不一致性
代理模式的应用场景
- 访问控制:确保只有授权的用户才能访问特定资源。
- 延迟加载:优化资源使用,提高性能。
- 远程访问:简化对远程对象的访问。
- 功能扩展:在不修改目标对象的情况下,添加额外功能。
- 简化接口:提供更易于使用的接口。
- 性能优化:通过缓存等机制提升系统性能。
- 协议适配:实现不同接口之间的兼容性。
- 资源管理:合理管理目标对象的资源使用。
- 版本控制:确保客户端使用最新版本。
- 日志记录和审计:记录操作日志,便于审计和分析。
代理模式的虚构故事
骆驼与巴巴羊的故事
骆驼:兔子,我家周围最近不太安全,有各种豺狼虎豹,你要不来我的沙漠派一些兵兔兔保护我好不好,保护费你随便开价。
兔子:我们从来不随便往别的地盘派遣兔兔尤其是兵兔兔,一般会派遣一些建筑队帮助修路、建桥之类的,再说了,现在整个村里局势比较敏感…
骆驼:思考了一会…, 那我在我的沙漠中给你批一块地,你来帮我搞搞建设、绿化下沙漠,好不好呀,听说你家沙漠治理也搞得不错。
兔子:这个嘛,这个是我擅长的领域,你找我干这个算是找对了…
later…
骆驼:兔子,最近我家这边不太平啊,连小蚂蚁都开始威胁我了,鹰酱和他穿一条裤子的,你能卖给我几个葫芦卜或者蘑菇吗,价钱好说,我不缺钱,我缺的是安全感。
兔子:你们之间的事,我不想掺和,不过我也不允许你被欺负,要不你找巴巴羊看看,他应该能帮上忙,前一阵白象惹事,巴巴羊用我家种的胡萝卜把白象打的鼻青脸肿的,灰头土脸跑了。
骆驼:哦,我貌似懂你的意思了…
later…
村广播站: 号外号外!! 骆驼和巴巴羊结拜为异父异母的亲兄弟…(骆驼家有钱、巴巴羊人多敢干、兔子家种的胡萝卜等农副产品可以作为武器)
分析:在这三个动物关系种,巴巴羊作为兔子的代理,卖给骆驼胡罗卜之类的农副产品
# 抽象主题
class Product(ABC):def sell_to(self, recv):pass# 真实主题
class Carrot(Product):""" 兔子家的胡萝卜"""def sell_to(self, recv):print(f"sell carrot to {recv}")# 代理主题
class BabayangProxy(Product):""" 巴巴羊二道贩子"""def __init__(self, product):self.product = productdef sell_to(self, recv):print(f"巴巴羊正在进行一场农副产品交易..")self.product.sell_to(recv)if __name__ == "__main__":carrot = Carrot()babayang_proxy = BabayangProxy(carrot) # 巴巴羊是兔子家的胡萝卜产品总代babayang_proxy.sell_to("骆驼")