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字段。那麼,如何給這個服務器設置一個白名單,使得只有白名單裏的地址可以訪問服務器呢?修改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和對白名單的操作。這樣,在場景中通過對白名單代理的訪問,就可以實現服務器的白名單訪問了。

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!
'''

 

二、代理模式

代理模式定義如下:爲某對象提供一個代理,以控制對此對象的訪問和控制。代理模式在使用過程中,應儘量對抽象主題類進行代理,而儘量不要對加過修飾和方法的子類代理。如上例中,如果有一個xServer繼承了Server,並新加了方法xMethod,xServer的代理應以Server爲主題進行設計,而儘量不要以xServer爲主題,以xServer爲主題的代理可以從ServerProxy繼承並添加對應的方法。

在JAVA中,講到代理模式,不得不會提到動態代理。動態代理是實現AOP(面向切面編程)的重要實現手段。而在Python中,很少會提到動態代理,而AOP則會以另一種模式實現:裝飾模式。有關AOP的相關內容,我們會在裝飾模式這一節中進行說明。

 

三、代理模式的優點和應用場景

優點:

1、職責清晰:非常符合單一職責原則,主題對象實現真實業務邏輯,而非本職責的事務,交由代理完成;
2、擴展性強:面對主題對象可能會有的改變,代理模式在不改變對外接口的情況下,可以實現最大程度的擴展;
3、保證主題對象的處理邏輯:代理可以通過檢查參數的方式,保證主題對象的處理邏輯輸入在理想範圍內。

應用場景:

1、針對某特定對象進行功能和增強性擴展。如IP防火牆、遠程訪問代理等技術的應用;
2、對主題對象進行保護。如大流量代理,安全代理等;
3、減輕主題對象負載。如權限代理等。

 

四、代理模式的缺點

1、可能會降低整體業務的處理效率和速度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章