声明:本系列文章主要参考《精通Python设计模式》一书,并且参考一些资料,结合自己的一些看法来总结而来。

  一、在某些应用中,我们想要在访问某个对象之前执行一个或者多个重要的操作,例如,访问敏感信息 -- 在允许用户访问敏感信息之前,我们希望确保用户具备足够的去权限。同时在网络访问时,限制某些网络的访问等操作。

  二、把一个计算成本较高的对象的创建过程延迟到用户首次真正使用它的时候才进行。

  以上的情况就可以使用 代理设计模式 。

  代理模式:因使用代理对象再访问实际对象之前执行重要操作而得其名。

  示例:

  之前想用《精通Python设计模式》中的示例来说明,但是发现很负责不太好理解,于是有了接下来的示例:阿里云:Python与设计模式 -代理模式

  一、首先构件一个网络服务器:

#该服务器接受如下格式数据,addr代表地址,content代表接收的信息内容
info_struct=dict()
info_struct["addr"]=10000
info_struct["content"]=""
class Server:
content=""
def recv(self,info):
pass
def send(self,info):
pass
def show(self):
pass
class infoServer(Server):
def recv(self,info):
self.content=info
return "recv OK!"
def send(self,info):
pass
def show(self):
print "SHOW:%s"%self.content

普通的网络服务器

  infoServer有接收和发送的功能,发送功能由于暂时用不到,保留。另外新加一个接口show,用来展示服务器接收的内容。接收的数据格式必须如info_struct所示,服务器仅接受info_struct的content字段。

  二、若此时有需求,该网络服务器只允许部分网络IP进行访问,那么需要设置白名单,该怎么做呢?显然可以有如下两种方式:

  ①、修改Server结构是个方法,即在进入server时,做一系列逻辑判断。但这显然不符合软件设计原则中的单一职责原则。

  ②、使用代理,即利用代理来进行逻辑判定,若在白名单中,则允许访问,若不在则拒绝。

class serverProxy:
pass
class infoServerProxy(serverProxy):
server=""
def __init__(self,server):
self.server=server
def recv(self,info):
return self.server.recv(info)
def show(self):
self.server.show() class whiteInfoServerProxy(infoServerProxy):
white_list=[]
def recv(self,info):
try:
assert type(info)==dict
except:
return "info structure is not correct"
addr=info.get("addr",0)
if not addr in self.white_list:
return "Your address is not in the white list."
else:
content=info.get("content","")
return self.server.recv(content)
def addWhite(self,addr):
self.white_list.append(addr)
def rmvWhite(self,addr):
self.white_list.remove(addr)
def clearWhite(self):
self.white_list=[]

  代理中有一个server字段,控制代理的服务器对象,infoServerProxy充当Server的直接接口代理,而whiteInfoServerProxy直接继承了infoServerProxy对象,同时加入了white_list和对白名单的操作。这样,在场景中使用一个白名单服务器代理类来实现,在接收请求时,做验证:内容是否符合规则、访问者的IP地址是否在白名单中,若通过则接收内容。

   那么有了白名单服务器代理,该怎么使用呢?

if  __name__=="__main__":
info_struct = dict()
info_struct["addr"] = 10010
info_struct["content"] = "Hello World!"
info_server = infoServer()
info_server_proxy = whiteInfoServerProxy(info_server)
print(info_server_proxy.recv(info_struct))
info_server_proxy.show()
info_server_proxy.addWhite(10010)
print (info_server_proxy.recv(info_struct))
info_server_proxy.show()

  打印如下:

Your address is not in the white list.
SHOW:
recv OK!
SHOW:Hello World!

  这边我也把书中的示例放置在此。

class LazyProperty(object):
'''利用装饰器的特性作为代理,给_resource初始化值'''
def __init__(self, method):
self.method = method
self.method_name = method.__name__
print('func name is:{}'.format(self.method_name)) def __get__(self, obj, cls):
'''使用值来替代方法'''
if not obj:
return None
value = self.method(obj)
print('value {}'.format(value))
setattr(obj, self.method_name, value)
return value class Test(object):
def __init__(self):
self.x = 'foo'
self.y = 'bar'
self._resource = None @LazyProperty # resource = LazyProperty(resource)
def resource(self):
print('init self._resource which is:{}'.format(self._resource))
self._resource = tuple(range(5))
return self._resource def main():
t = Test()
print(t.x)
print(t.y)
print(t._resource)
print(t.resource)
print(t.__dict__)
print(t.resource)
# print(t._resource) if __name__ == '__main__':
main()

精通Python设计模式--示例

 该示例:使用的是装饰器来实现对 resource方法的惰性加载,而该装饰器是使用数据描述符来实现的,故需要对数据描述符有一定的了解。

  over~~,参考:https://yq.aliyun.com/articles/70738?utm_content=m_15329,感谢。。。

最新文章

  1. 编写Javascript类库(jQuery版) - 进阶者系列 - 学习者系列文章
  2. 51nod1069(nim博弈)
  3. WebDriver使用指南(完整篇)
  4. 静态HTML页面不缓存js文件的方法
  5. MITK Tutorial (三)
  6. JDK版本1.6和6.0到底指什么
  7. 将Activity设置成半透明的对话框
  8. WPF笔记(1.6 数据绑定)——Hello,WPF!
  9. return break continue 的区别
  10. 根据屏幕自适应宽度:@media
  11. 《R数据挖掘入门》彩色插图(第8章)
  12. spring boot 事务配置
  13. ifconfig不显示网卡eth0
  14. Java对象池
  15. express统一输出404页面
  16. [AngularJS]ng-repeat指令要点
  17. 2018.09.28 牛客网contest/197/C期望操作数(状态转移+前缀和递推)
  18. [大数据可视化]-saiku的源码包Bulid常见问题和jar包
  19. iOS基础教程:在建好的项目中加入CoreData[转]
  20. Git命令使用大全

热门文章

  1. 凤翔中学高三数学[备课&作业]
  2. 开发中常用linux命令
  3. pycharm默认注释与快捷键功能
  4. c++功能与方法笔记
  5. 【Gamma】“北航社团帮”展示博客
  6. shell (二) shell for循环
  7. 数据库连接池, websocket
  8. 正则表达式之re模块
  9. [转帖]centos7 使用kubeadm 快速部署 kubernetes 国内源
  10. 【Appium + Python3】之安卓8.1,使用xpath定位不到元素