结构型模式之代理模式

举报
子都爱学习 发表于 2022/02/27 18:18:29 2022/02/27
【摘要】 代理模式为另一个对象提供一个代理或占位者,来控制对该对象的访问。意图确保类有且只有一个对象被创建为对象提供一个访问点,以使程序可以全局访问对象控制共享资源的并行访问                            优点代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;代理对象可以扩展目标对象的功能;代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加...

代理模式

为另一个对象提供一个代理或占位者,来控制对该对象的访问。

意图

  • 确保类有且只有一个对象被创建
  • 为对象提供一个访问点,以使程序可以全局访问对象
  • 控制共享资源的并行访问

                           

优点

  • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
  • 代理对象可以扩展目标对象的功能;
  • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性


实现

1.抽象主题(Subject)类

通过接口或抽象类声明真实主题和代理对象实现的业务方法。

from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def do_play(self):
        pass

2.真实主题(Real Subject)类

实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。

class Bank(Payment):
    def __init__(self):
        self.card = None
        self.account = None

    def __getAccount(self):
        # 简化, 卡号就是账户号
        self.account = self.card
        return self.account

    def __hasFunds(self):
        # 简化,账户号就是金钱数
        funds = int(self.__getAccount())
        if funds > 1000:
            print("Bank:: Checking if Account", self.__getAccount(), "has enough funds")
            return True
        else:
            print("Bank:: Checking if Account", self.__getAccount(), "has not enough funds")
            return False

    def setCard(self, card):
        self.card = card

    def do_play(self):
        if self.__hasFunds():
            print("Bank:: Paying the merchant")
            return True
        else:
            print("Bank:: Sorry, not enough funds!")
            return False

3.代理(Proxy)类

提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

class DebitCard(Payment):
    def __init__(self):
        self.bank = Bank()

    def do_play(self):
        card = input("Proxy: Punch in card Number")
        self.bank.setCard(card)
        return self.bank.do_play()

3.客户端类

class LiDogEag:
    def __init__(self):
        print("You:: lets buy the Denim shirt!")
        self.debitCard = DebitCard()
        self.isPurchased = None

    def make_payment(self):
        self.isPurchased = self.debitCard.do_play()

    def __del__(self):
        if self.isPurchased:
            print('You:: Wow!,Denim shirt is Mine!')
        else:
            print("You:: I should earn more. 555...")

You = LiDogEag()
You.make_payment()

李狗蛋(客户端)去商场买牛仔衫,现金不够付款(抽象主题类),但是银行(真实主题类)取钱又太远,于是他使用信用卡(代理类)代付,如果账户前足够则付款成功得到牛仔衫,不够则无法购买。

缺点

  • 代理模式会造成系统设计中类的数量增加
  • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
  • 增加了系统的复杂度;


应用

  • 远程代理,这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如,用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
  • 虚拟代理,这种方式通常用于要创建的目标对象开销很大时。例如,下载一幅很大的图像需要很长时间,因某种计算比较复杂而短时间无法完成,这时可以先用小比例的虚拟代理替换真实的对象,消除用户对服务器慢的感觉。
  • 安全代理,这种方式通常用于控制不同种类客户对真实对象的访问权限。
  • 智能指引,主要用于调用目标对象时,代理附加一些额外的处理功能。例如,增加计算真实对象的引用次数的功能,这样当该对象没有被引用时,就可以自动释放它。
  • 延迟加载,指为了提高系统的性能,延迟对目标的加载。例如,Hibernate 中就存在属性的延迟加载和关联表的延时加载。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。