5-Python與設計模式–代理模式
一、網絡服務器配置白名單
代理模式是一種使用頻率非常高的模式,在多個著名的開源軟件和當前多個著名的互聯網產品后
臺程序中都有所應用。下面我們用一個抽象化的簡單例子,來說明代理模式。
首先,構造一個網絡服務器:
#該服務器接受如下格式數據,addr代表地址,content代表接收的信息內容
info_struct=dict()
info_struct["addr"]=10000
info_struct["content"]=""
class Server:content=""def recv(self,info):passdef send(self,info):passdef show(self):pass
class infoServer(Server):def recv(self,info):self.content=inforeturn "recv OK!"def send(self,info):passdef 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=serverdef 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)==dictexcept: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"] = 10010info_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的相關內容,
我們會在裝飾模式這一節中進行說明。
三、代理模式的優點和應用場景
3.1 優點:
1、職責清晰:非常符合單一職責原則,主題對象實現真實業務邏輯,而非本職責的事務,交由代理完成;
2、擴展性強:面對主題對象可能會有的改變,代理模式在不改變對外接口的情況下,可以實現最大程度的擴展;
3、保證主題對象的處理邏輯:代理可以通過檢查參數的方式,保證主題對象的處理邏輯輸入在理想范圍內。
3.2 應用場景:
1、針對某特定對象進行功能和增強性擴展。如IP防火墻、遠程訪問代理等技術的應用;
2、對主題對象進行保護。如大流量代理,安全代理等;
3、減輕主題對象負載。如權限代理等。
四、代理模式的缺點
1、可能會降低整體業務的處理效率和速度。