淺談Python設(shè)計模式 - 代理模式

聲明:本系列文章主要參考《精通Python設(shè)計模式》一書舵抹,并且參考一些資料苏携,結(jié)合自己的一些看法來總結(jié)而來贝室。

一、在某些應(yīng)用中畸裳,我們想要在訪問某個對象之前執(zhí)行一個或者多個重要的操作缰犁,例如,訪問敏感信息 -- 在允許用戶訪問敏感信息之前怖糊,我們希望確保用戶具備足夠的去權(quán)限帅容。同時在網(wǎng)絡(luò)訪問時,限制某些網(wǎng)絡(luò)的訪問等操作伍伤。

二丰嘉、把一個計算成本較高的對象的創(chuàng)建過程延遲到用戶首次真正使用它的時候才進(jìn)行。

以上的情況就可以使用 代理設(shè)計模式 嚷缭。

代理模式:因使用代理對象再訪問實際對象之前執(zhí)行重要操作而得其名。

示例:

之前想用《精通Python設(shè)計模式》中的示例來說明,但是發(fā)現(xiàn)很負(fù)責(zé)不太好理解阅爽,于是有了接下來的示例:阿里云:Python與設(shè)計模式 -代理模式路幸。

一、首先構(gòu)件一個網(wǎng)絡(luò)服務(wù)器:

#該服務(wù)器接受如下格式數(shù)據(jù)付翁,addr代表地址简肴,content代表接收的信息內(nèi)容
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有接收和發(fā)送的功能,發(fā)送功能由于暫時用不到百侧,保留砰识。另外新加一個接口show,用來展示服務(wù)器接收的內(nèi)容佣渴。接收的數(shù)據(jù)格式必須如info_struct所示辫狼,服務(wù)器僅接受info_struct的content字段。

二辛润、若此時有需求膨处,該網(wǎng)絡(luò)服務(wù)器只允許部分網(wǎng)絡(luò)IP進(jìn)行訪問,那么需要設(shè)置白名單砂竖,該怎么做呢真椿?顯然可以有如下兩種方式:

①、修改Server結(jié)構(gòu)是個方法乎澄,即在進(jìn)入server時突硝,做一系列邏輯判斷。但這顯然不符合軟件設(shè)計原則中的單一職責(zé)原則置济。

②解恰、使用代理,即利用代理來進(jìn)行邏輯判定舟肉,若在白名單中修噪,則允許訪問,若不在則拒絕路媚。

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字段黄琼,控制代理的服務(wù)器對象,infoServerProxy充當(dāng)Server的直接接口代理整慎,而whiteInfoServerProxy直接繼承了infoServerProxy對象脏款,同時加入了white_list和對白名單的操作。這樣裤园,在場景中使用一個白名單服務(wù)器代理類來實現(xiàn)撤师,在接收請求時,做驗證:內(nèi)容是否符合規(guī)則拧揽、訪問者的IP地址是否在白名單中剃盾,若通過則接收內(nèi)容腺占。

那么有了白名單服務(wù)器代理,該怎么使用呢痒谴?

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!

這邊我也把書中的示例放置在此衰伯。

class LazyProperty(object):
    '''利用裝飾器的特性作為代理,給_resource初始化值'''
    def __init__(self, method):
        self.method = method
        self.method_name = method.__name__
        print('func name is:{}'.format(self.method_name))

    def __get__(self, obj, cls):
        '''使用值來替代方法'''
        if not obj:
            return None
        value = self.method(obj)
        print('value {}'.format(value))
        setattr(obj, self.method_name, value)
        return value


class Test(object):
    def __init__(self):
        self.x = 'foo'
        self.y = 'bar'
        self._resource = None
    
    @LazyProperty   # resource = LazyProperty(resource)
    def resource(self):
        print('init self._resource which is:{}'.format(self._resource))
        self._resource = tuple(range(5))
        return self._resource
    
def main():
    t = Test()
    print(t.x)
    print(t.y)
    print(t._resource)
    print(t.resource)
    print(t.__dict__)
    print(t.resource)
    # print(t._resource)

if __name__ == '__main__':
    main()

該示例:使用的是裝飾器來實現(xiàn)對 resource方法的惰性加載积蔚,而該裝飾器是使用數(shù)據(jù)描述符來實現(xiàn)的意鲸,故需要對數(shù)據(jù)描述符有一定的了解。

over~~尽爆,參考:https://yq.aliyun.com/articles/70738?utm_content=m_15329怎顾,感謝。漱贱。槐雾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市饱亿,隨后出現(xiàn)的幾起案子蚜退,更是在濱河造成了極大的恐慌,老刑警劉巖彪笼,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钻注,死亡現(xiàn)場離奇詭異,居然都是意外死亡配猫,警方通過查閱死者的電腦和手機(jī)幅恋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泵肄,“玉大人捆交,你說我怎么就攤上這事「玻” “怎么了品追?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長冯丙。 經(jīng)常有香客問我肉瓦,道長,這世上最難降的妖魔是什么胃惜? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任泞莉,我火速辦了婚禮,結(jié)果婚禮上船殉,老公的妹妹穿的比我還像新娘鲫趁。我一直安慰自己,他們只是感情好利虫,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布挨厚。 她就那樣靜靜地躺著堡僻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疫剃。 梳的紋絲不亂的頭發(fā)上苦始,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音慌申,去河邊找鬼。 笑死理郑,一個胖子當(dāng)著我的面吹牛蹄溉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播您炉,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼柒爵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赚爵?” 一聲冷哼從身側(cè)響起棉胀,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冀膝,沒想到半個月后唁奢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡窝剖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年麻掸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赐纱。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡脊奋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疙描,到底是詐尸還是另有隱情诚隙,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布起胰,位于F島的核電站久又,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏待错。R本人自食惡果不足惜籽孙,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望火俄。 院中可真熱鬧犯建,春花似錦、人聲如沸瓜客。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至玻熙,卻和暖如春否彩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗦随。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工列荔, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人枚尼。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓贴浙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親署恍。 傳聞我的和親對象是個殘疾皇子崎溃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容