裝飾器模式以及在Python下的實(shí)現(xiàn)

什么是 開放-封閉原則

開放是對(duì)擴(kuò)展開放,也就是能支持功能的擴(kuò)展
封閉是對(duì)原功能封閉,這意思是當(dāng)功能擴(kuò)展的時(shí)候并不用更改原來(lái)的代碼

什么是裝飾器模式

裝飾器模式就是在不改變?cè)瓉?lái)代碼的基礎(chǔ)上增加原來(lái)方法的功能

舉個(gè)例子

比如有一個(gè)方法叫 method1()

現(xiàn)在需要在method1調(diào)用的時(shí)候進(jìn)行日志記錄

一般做法是

log()
method1()

但是這樣的問(wèn)題是 所有調(diào)用method1()的地方都要添加log()。多處進(jìn)行更改。

我們需要的是外部的所有調(diào)用還是method1()來(lái)調(diào)用,而method1()執(zhí)行的時(shí)候添加了日志功能,并且還不能更改method1()原來(lái)的代碼。因?yàn)槿绻?code>method1的代碼的話,那么后面如果再需要添加一個(gè)權(quán)限校驗(yàn)功能就又需要改method1的代碼。不符合封閉原則。

這個(gè)時(shí)候就可以用裝飾器模式來(lái)解決這個(gè)問(wèn)題。

下面以Python語(yǔ)言為例

首先需要說(shuō)明的是在Python中,函數(shù)名其實(shí)就是一個(gè)指向函數(shù)體的一個(gè)指針。(應(yīng)該在所有語(yǔ)言中都是這樣的)

即下面這種情況 m2()method1()是一樣的。都是指向了同一個(gè)方法體

m2 = method1
m2()

如圖所示

那么對(duì)于方法功能擴(kuò)展就可以這樣來(lái)

def w():
    def inner():
        print('log')
    return inner

m = w()

m()

當(dāng)調(diào)用w()時(shí),返回的其實(shí)就是inner函數(shù)的函數(shù)指針

然后m()執(zhí)行,其實(shí)也就是inner()執(zhí)行。所以就輸出log

那么此時(shí)w()這個(gè)函數(shù)和method1還沒(méi)有產(chǎn)生關(guān)系。

現(xiàn)在,我們讓inner執(zhí)行的時(shí)候去執(zhí)行method1


def method1():
    print('method1 do something...')

def w(func):
    def inner():
        print('log')
        func()
    return inner
    
m2 = w(method1)
m2()

現(xiàn)在來(lái)解釋一下這段代碼。

首先是method1的定義

然后是一個(gè)w方法的定義,w接受一個(gè)參數(shù)

接下來(lái)調(diào)用w,w將內(nèi)部的inner函數(shù)返回。用m2指向inner函數(shù)

調(diào)用m2也就是調(diào)用inner

inner()函數(shù)執(zhí)行,首先輸出log,然后執(zhí)行func(),這個(gè)func()方法也就是w()傳入的參數(shù)。此處即method1

這樣最終執(zhí)行結(jié)果就是

先調(diào)用日志功能,此處即輸出log

再執(zhí)行method1

但是,外部調(diào)用的method1(),如果像上面這樣需要都改為m2()。我們需要不影響外部調(diào)用 。

如下修改

def method1():
    print('method1 do something...')

def w(func):
    def inner():
        print('log')
        func()
    return inner
    
method1 = w(method1)
method1()

我們讓method1重新指向inner函數(shù)的地址

這樣外部所有的調(diào)用還是調(diào)用method1() ,但是該方法已經(jīng)添加了日志功能

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,641評(píng)論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,740評(píng)論 18 399
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,074評(píng)論 0 9
  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。簡(jiǎn)單...
    舟漁行舟閱讀 8,131評(píng)論 2 17
  • 不懂愛,渴望愛,一直在找尋愛。 我朋友說(shuō),我夢(mèng)到的小紅帽,就是一直在找尋的象征。我說(shuō),小紅帽充滿希望,但很容易相信...
    法棍紅辣椒閱讀 147評(píng)論 0 0

友情鏈接更多精彩內(nèi)容