代理模式在日常生活中很常见,比如,你去杂货店买一个插座,而不是去生产插座的工厂去买。再比如,你去访问某个网站,你并没有访问权限,但你可以通过代理去访问这个网站,然后代理再把内容传给你。讲代理模式之前,先讲下正向代理和反向代理的区别:
正向代理
上面访问网站的例子就是正向代理,可以用下面的流程图展示这一机制。
正向代理:客户端访问某网站,先访问代理,代理去访问某网站,然后把内容返回给客户端,这就是正向代理。正向代理就是我们现实中常用的代理模式。杂货店代理工厂的产品,火车票代售点代理火车票业务等等。
反向代理
如下图
反向代理:客户端去访问某个网站的某个资源,但这个网站没有这个资源,同时这个网站被设置为反向代理,那么这个网站就会从其他服务器上获取这个资源返回给客户端。因此客户端并不知道这个资源是谁提供的,它只要知道代理网站的网站即可。比如我们访问百度,背后有成千上万的反向代理服务器在为我们服务,但我们只要知道baid.com这个网站就行了,不必知道访问的资料具体来自哪里。nginx是高流量web服务器流行选择,它支持反向代理和负载均衡。
代理模式
代理模式就是给对象提供一个代理,用来控制对对象的访问。比如,对于网站中用户经常访问的资源,可以用redis数据库进行存储,以加快网站响应速度。下面实现了网站对常用资源访问设置缓存的设计。
Source类是网站常用资源,source_proxy是常用资源的代理类,client是客户端,cache类存储了常用的访问资源。具体实现如下代码
# author guoyibo
class Cache(object):
"""
use for save source that ofen is requested
"""
def __init__(self):
self.cache = {}
def get(self, key):
return self.cache.get(key)
def set(self, key, value):
self.cache[key] = value
print('set %s to %s' % (value, key))
cache = Cache()
class Souce(object):
def __init__(self, name):
self.name = name
@property
def obtain(self):
print('get source from source')
return 'source of %s' % self.name
class Source_proxy(object):
def __init__(self, source):
self.source = source
@property
def obtain(self):
content = cache.get(self.source.name)
if not content:
content = self.source.obtain
cache.set(self.source.name, content)
else:
print('get source from cache')
return content
class Client(object):
def __init__(self, source):
self.source = source
def show(self):
print('from backend get source %s' % self.source.obtain)
if __name__ == '__main__':
source = Souce('picture.jpg')
proxy = Source_proxy(source)
# first visit
client = Client(proxy)
client.show()
# second visit
print('*'*20)
client.show()
结果如下
get source from source
set source of picture.jpg to picture.jpg
from backend get source source of picture.jpg
********************
get source from cache
from backend get source source of picture.jpg