python-设计模式(2)
- 代理模式
为另一个对象提供一个替身或占位符以控制对这个对象的访问

#该服务器接受如下格式数据,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
定义了一个infoSever(继承自server,注意server下侧全为pass,方法主要由后面的子类来重写),其拥有recv和send,show功能
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=[]
拥有serverproxy类(也就是根据server建立的代理),infoserverproxy类(细化了recv和show的功能),whiteinfoserverproxy类(添加了白名单功能),三者层层继承
其命名也是一个逐渐添加功能的形式,这样也符合类的单一职责原则
如果有一个xServer继承了Server,并新加了方法xMethod,xServer的代理应以Server为主题进行设计,而尽量不要以xServer为主题
以xServer为主题的代理可以从ServerProxy继承并添加对应的方法。
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()
首先定义一个传入信息,然后实例化infoserver这个类,使用含有白名单的方法,传入实例
将10010传入白名单,最后即可收入该信息
输出如下:
Your address is not in the white list. SHOW: recv OK! SHOW:Hello World!
优点:
1、职责清晰:非常符合单一职责原则,主题对象实现真实业务逻辑,而非本职责的事务,交由代理完成;
2、扩展性强:面对主题对象可能会有的改变,代理模式在不改变对外接口的情况下,可以实现最大程度的扩展;
3、保证主题对象的处理逻辑:代理可以通过检查参数的方式,保证主题对象的处理逻辑输入在理想范围内。
应用场景:
1、针对某特定对象进行功能和增强性扩展。如IP防火墙、远程访问代理等技术的应用;
2、对主题对象进行保护。如大流量代理,安全代理等;
3、减轻主题对象负载。如权限代理等。
- 装饰器模式
动态地给一个对象添加一些额外的职责。在增加功能方面,装饰器模式比生成子类更为灵活

装饰器模式和代理模式非常相似,可以认为,装饰器模式就是代理模式的一个特殊应用,两者的共同点是都具有相同的接口,不同点是侧重对主题类的过程的控制,而装饰模式则侧重对类功能的加强或减弱
AOP即Aspect Oriented Programming,中文翻译为面向切面的编程,它的含义可以解释为:如果几个或更多个逻辑过程中(这类逻辑过程可能位于不同的对象,不同的接口当中),有重复的操作行为,就可以将这些行为提取出来(即形成切面),进行统一管理和维护。举例子说,系统中需要在各个地方打印日志,就可以将打印日志这一操作提取出来,作为切面进行统一维护
class drinkDecorator(): def getName(self): pass def getPrice(self): pass class iceDecorator(drinkDecorator): def __init__(self,beverage): self.beverage=beverage def getName(self): return self.beverage.getName()+" +ice" def getPrice(self): return self.beverage.getPrice()+0.3 class sugarDecorator(drinkDecorator): def __init__(self,beverage): self.beverage=beverage def getName(self): return self.beverage.getName()+" +sugar" def getPrice(self): return self.beverage.getPrice()+0.5
为饮料添加一个装饰器类,iceDecorator和sugarDecorator,每个装饰器类可以对功能进行一些改变
if __name__=="__main__": coke_cola=coke() print "Name:%s"%coke_cola.getName() print "Price:%s"%coke_cola.getPrice() ice_coke=iceDecorator(coke_cola) print "Name:%s" % ice_coke.getName() print "Price:%s" % ice_coke.getPrice()
此处使用装饰器功能,为其原操作进行了一些微调
输出如下
Name:coke Price:4.0 Name:coke +ice Price:4.3
python自身也有装饰器的功能
def log(func): def wrapper(*args, **kw): print 'call %s():' % func.__name__ return func(*args, **kw) return wrapper @log def now(): print '2016-12-04' if __name__=="__main__": now()
log为一个装饰器(函数形式,参数为函数名),其内部嵌套一个wrapper函数,返回操作结果,log装饰器返回内部定义的函数
(装饰器以函数名为参数,在内部定义一个函数(这个函数会完成关于函数名的操作),再返回这个内部定义的函数
输出为
call now():
2016-12-04
优点:
1、装饰器模式是继承方式的一个替代方案,可以轻量级的扩展被装饰对象的功能;
2、Python的装饰器模式是实现AOP的一种方式,便于相同操作位于不同调用位置的统一管理。
应用场景:
1、需要扩展、增强或者减弱一个类的功能,如本例
- 适配器模式

浙公网安备 33010602011771号