1. 程式人生 > >結構類設計模式(7種)之代理模式

結構類設計模式(7種)之代理模式

結構類設計模式(7種)之代理模式

目錄

結構類設計模式(7種)之代理模式

一、網路伺服器配置白名單

二、代理模式

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

四、代理模式的缺點


一、網路伺服器配置白名單

代理模式是一種使用頻率非常高的模式,在多個著名的開源軟體和當前多個著名的網際網路產品後臺程式中都有所應用。下面我們用一個抽象化的簡單例子,來說明代理模式。
首先,構造一個網路伺服器:

 

#該伺服器接受如下格式資料,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繼承並新增對應的方法。


f1.png


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

 

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

優點:

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

應用場景:

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

 

四、代理模式的缺點

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