Loading

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、需要扩展、增强或者减弱一个类的功能,如本例

  • 适配器模式

 

posted @ 2020-11-06 17:35  lixin2020  阅读(92)  评论(0)    收藏  举报