zoukankan      html  css  js  c++  java
  • [Python设计模式] 第7章 找人帮忙追美眉——代理模式

    github地址:https://github.com/cheesezh/python_design_patterns

    题目1

    Boy追求Girl,给Girl送鲜花,送巧克力,送洋娃娃。

    class Boy():
        def __init__(self, girl):
            self.girl = girl
        
        def give_dolls(self):
            print("{}, 送你洋娃娃".format(self.girl.name))
        
        def give_flowers(self):
            print("{}, 送你鲜花".format(self.girl.name))
    
        def give_chocolate(self):
            print("{}, 送你巧克力".format(self.girl.name))
            
    class Girl():
        def __init__(self, name):
            self.name = name
        
    def main():
        mm = Girl("曼曼")
        gg = Boy(mm)
        
        gg.give_dolls()
        gg.give_chocolate()
        gg.give_flowers()
    
    main()
    
    曼曼, 送你洋娃娃
    曼曼, 送你巧克力
    曼曼, 送你鲜花
    

    题目2

    假设Boy并不认识Girl,Boy希望让Proxy帮他把鲜花,巧克力,洋娃娃转交给Girl。

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

    点评

    这样看上去的确是Proxy送给Girl的各种礼物,但是这些礼物其实是Boy的,在代码中并没有体现这一点。在代码中如何体现表面上是Proxy送的礼物,实际上是Boy送的礼物呢?这需要用到代理模式,把送礼物封装成接口,然后让Boy和Proxy都去实现这个接口,Boy和Proxy的区别就是Proxy的接口实现要调用Boy的接口实现。

    Python中没有明确的接口定义方法,抽象接口可以看作编程人员对自己编码行为的约束,让自己按照一定的规矩写代码。为了实现同样的目的,在Python中可以通过定义一个抽象类来达到相同的目的。

    from abc import ABCMeta, abstractmethod
    
    
    class IGiveGift():
    
        __metaclass__ = ABCMeta
        
        @abstractmethod
        def give_dolls(self):
            pass
        
        @abstractmethod
        def give_flowers(self):
            pass
        
        @abstractmethod
        def give_chocolate(self):
            pass
        
        
    class Boy(IGiveGift):
        
        def __init__(self, girl):
            self.girl = girl
        
        def give_dolls(self):
            print("{}, 送你洋娃娃".format(self.girl.name))
        
        def give_flowers(self):
            print("{}, 送你鲜花".format(self.girl.name))
    
        def give_chocolate(self):
            print("{}, 送你巧克力".format(self.girl.name))
            
            
    class Proxy(IGiveGift):
        
        def __init__(self, girl):
            self.gg = Boy(girl)
        
        def give_dolls(self):
            self.gg.give_dolls()
        
        def give_flowers(self):
            self.gg.give_flowers()
    
        def give_chocolate(self):
            self.gg.give_chocolate()
            
    def main():
        mm = Girl("曼曼")
        proxy = Proxy(mm)
        
        proxy.give_dolls()
        proxy.give_chocolate()
        proxy.give_flowers()
    
    main()
    
    曼曼, 送你洋娃娃
    曼曼, 送你巧克力
    曼曼, 送你鲜花
    

    点评

    现在从代码中可以清晰的看出,表面上是proxy送给Girl mm的礼物,但是其实是Boy gg送的。

    代理模式

    代理模式,为其他对象提供一种代理以控制对这个对象的访问。在上述场景中,mm和gg并没有直接的联系,即mm和gg互相无法访问到,但是可以通过proxy来达到gg送mm礼物的效果。

    代理模式主要包括三种类:

    • Subject类:例如IGiveGift类,定义了RealSubject和Proxy的功用接口,这样就在任何使用RealSubject的地方使用Proxy;
    • RealSubject类:例如Boy类,定义Proxy所代表的真实实体;
    • Proxy类:例如Porxy类,保存一个引用是的代理可以访问实体,并提供一个于Subject的接口相同的接口,这样代理就可以用来代替实体;

    代理模式应用主要包括以下几种:

    • 远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实[DP]。
    • 虚拟代理,是根据需要创建开销很大的对象。通过它来存在实例化需要很长时间的真实对象[DP]。浏览器优化下载就是用的代理模式,例如打开一个很大的HTML网页时,里面可能由很多文字和图片,但是依然可以很快打开,优先看到文字,但是图片还在一张一张下载。哪些未打开的图片框,就是通过虚拟代理来替代真实图片,此时代理存储了真实图片的路径和尺寸。
    • 安全代理,用来控制真实对象访问时的权限[DP]。一般用于对象应该有不同的访问权限的时候。
    • 智能指引,是指当调用真实的对象时,代理处理另外一些事[DP]。例如计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它;或者当第一引用一个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它。这些都是通过代理在访问一个对象时附加一些内务处理。
  • 相关阅读:
    爱加密亮相第十八届软博会,移动App安全引关注
    android 实现自己定义状态栏通知(Status Notification)
    Android中View绘制流程以及invalidate()等相关方法分析
    设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
    目标检測的图像特征提取之(一)HOG特征
    Vbox 未指定XXX网络名称 找不到网卡问题
    NetBeans工具学习之道:NetBeans IDE Java 高速新手教程
    NETSH WINSOCK RESET这条命令的含义和作用?
    红帽/CentOS ext4无法格式化大分区 补充ext4格式化方式
    android之PackageManager简单介绍
  • 原文地址:https://www.cnblogs.com/CheeseZH/p/9384214.html
Copyright © 2011-2022 走看看