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]。例如计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它;或者当第一引用一个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它。这些都是通过代理在访问一个对象时附加一些内务处理。

[Python设计模式] 第7章 找人帮忙追美眉——代理模式的更多相关文章

  1. [Python设计模式] 第26章 千人千面,内在共享——享元模式

    github地址:https://github.com/cheesezh/python_design_patterns 背景 有6个客户想做产品展示网站,其中3个想做成天猫商城那样的"电商风 ...

  2. [Python设计模式] 第9章 如何准备多份简历——原型模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 设计一个简历类,必须有姓名,可以设置性别和年龄,即个人信息,可以设置曾就职 ...

  3. [Python设计模式] 第15章 如何兼容各种DB——抽象工厂模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 如何让一个程序,可以灵活替换数据库? 基础版本 class User(): ...

  4. js设计模式系列之(一)请节约你的请求-代理模式

    What’s the proxy pattern? 代理模式其实就是将违反单一性原则的类给抽离出来,尽量满足开放和封闭的原则. 相当于一个类的行为只是一种,但是你可以给这个类添加额外的行为.比如: 一 ...

  5. [Python设计模式] 第21章 计划生育——单例模式

    github地址:https://github.com/cheesezh/python_design_patterns 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式 ...

  6. [Python设计模式] 第8章 学习雷锋好榜样——工厂方法模式

    github地址:https://github.com/cheesezh/python_design_patterns 简单工厂模式 v.s. 工厂方法模式 以简单计算器为例,对比一下简单工厂模式和工 ...

  7. [Python设计模式] 第1章 计算器——简单工厂模式

    github地址:https://github.com/cheesezh/python_design_patterns 写在前面的话 """ 读书的时候上过<设计模 ...

  8. [Python设计模式] 第28章 男人和女人——访问者模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 用程序模拟以下不同情况: 男人成功时,背后多半有一个伟大的女人: 女人成功 ...

  9. [Python设计模式] 第22章 手机型号&软件版本——桥接模式

    github地址:https://github.com/cheesezh/python_design_patterns 紧耦合程序演化 题目1 编程模拟以下情景,有一个N品牌手机,在上边玩一个小游戏. ...

随机推荐

  1. Oracle 11.2.0.4 For Windows 64bit+32bit 数据库

    1.Oracle11G 32BIT介质官方链接 适用于Windows 32bit的Oracle Database 11G 第2版U4(11.2.0.4)Oracle11.2.0.4  Windows3 ...

  2. Codeforces 1000F One Occurrence 主席树|| 离线+线段树

    One Occurrence 为什么我半年前这么菜呀, 这种场只A三题... 我们在主席树 || 线段树上维护每个数的右边和它一样的数在哪里, 然后就变成了区间求最大值. 注意加进去的时候要把它右边一 ...

  3. Codeforces Round #319 (Div. 2) E - Points on Plane

    题目大意:在一个平面里有n个点,点坐标的值在1-1e6之间,让你给出一个遍历所有点的顺序,要求每个点走一次,且 曼哈顿距离之和小于25*1e8. 思路:想了一会就有了思路,我们可以把1e6的x,y坐标 ...

  4. 菜单联动,select联动菜单(搜索之后默认选中)

    框架:thinkphp php控制器代码: $schedulelist = M('schedule')->getField('sid,schedule_name'); $this->ass ...

  5. Storm中关于Topology的设计

    一:介绍Storm设计模型 1.Topology Storm对任务的抽象,其实 就是将实时数据分析任务 分解为 不同的阶段 点: 计算组件   Spout   Bolt 边: 数据流向    数据从上 ...

  6. Unity3d和Android之间互相调用

    摘抄博客 Unity3d Android SDK接入解析(一)Unity3d 与 Android之间的互相调用,一共四章,一定要看完 No1: 总体来说Unity3d与Android之间的互相调用,是 ...

  7. 洛谷 p1434 滑雪【记忆化搜索】

    <题目链接> Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  8. 一个基于C++11的定时器队列(timerfd,poll实现)

    目录 前言 优点 test 源代码 @ 前言 最近小程序要用到定时器,找了一圈也没找到合适的,最后还是绕回来选择了muduo里面的TimerQueue,整理了下它的代码,独立了出来,因为实在懒得从头写 ...

  9. 使用boost线程定时器作为后台线程来切换主循环程序状态方法2

    上一篇的方法主要使用的是:通过线程延时实 现的定时,并且只能定时一次,如果需要对此定时处理,就需要使用下面的定时器: #include "stdafx.h" #include &l ...

  10. 系统windows版本修改

    系统基本信息修改 系统windows版本修改 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: 313134555 @qq.com ...