一、全部書中都沒有把猴子補丁做爲一種設計模式來看待。由於設計模式的模式的命名是根據java中提煉出來的,語言方式決定了java絕對不會有也不須要有這種操做,不存在的。那天然設計模式不會包括猴子補丁模式。html
二、根據百度百科介紹,設計模式(Design pattern)表明了最佳的實踐,一般被有經驗的面向對象的軟件開發人員所採用。設計模式是軟件開發人員在軟件開發過程當中面臨的通常問題的解決方案。這些解決方案是衆多軟件開發人員通過至關長的一段時間的試驗和錯誤總結出來的。只要是解決高可擴展和高可複用的編碼問題就能夠算是一種設計模式,猴子補丁是在python裏面一種很廣泛達到這種目的方式,因此能夠算是一種設計模式。java
三、在python 函數和類和全局變量都是一等公民,不是全部東西必須都要寫到一個類裏面包裹起來,寫起來很自由。有的python人員c語言中毒太深或者連c語言都沒學過只自學python,寫代碼項目裏面永遠只會有0個類(除開文檔上規定死了要寫一個類的這種類),模塊加函數的寫法只能解決局部複用,和類的可複用性相比差距很大。可是別人就是打死也不肯意項目裏面有一個類出現,這種狀況怎麼改造這個模塊的總體功能?python
假設有個文件叫 xxx.py, 且xxx.py代碼以下:編程
_var_aaa = 1設計模式
def _function_bbb(paramx):閉包
return paramx * 10函數
def function_ccc(paramx):oop
print(_var_aaa) # 這裏假設是print,實際確定是拿着var_aaa變量作實際有意義的事情post
_function_bbb(paramx)編碼
do_othrething() ................................
模塊的function_ccc函數是惟一 做爲公有函數,是但願被外界調用的。但這個函數很蛋疼,依賴了模塊/包 裏面的外部變量和外部函數,要改他並非改這個函數自己就能達到目的,還要改其餘地方。
假如但願全局變量 _var_aaa的初始值是2,函數_function_bbb的功能是吧變量擴大100倍,怎麼改?
1)、去修改源文件,確定不靠譜,你硬編碼的方式改了這裏的代碼,若是沒通知別人,別人繼續使用,別人調用函數會出來新的結果會出毛病。並且猴子補丁不少時候是針對三方包或者官方包,去直接修改那些地方的文件很不靠譜,任什麼時候候都不要這麼作。
2)、把整個包/模塊複製出來一份,而後修改其中的一小部分幾行代碼,殺雞用牛刀,爲了0.01%代碼的改變,平白無故增長几千幾萬行相同字母的代碼。
以上兩種方法都很差,在最小代價下實現 全局變量 _var_aaa的初始值是2,函數__function_bbb的功能是吧變量擴大100倍,應該就是輪到猴子補丁上場了,
import xxx
xxx._var_aaa = 2
def _my_function_bbb(paramx):
return paramx * 100
xxx._function_bbb = _my_function_bbb
以後再次調用 function_ccc,就會使改變生效了,不止當前代碼模塊處會生效,運行patch後會使全部地方生效。
猴子補丁賴以實現的基礎是
四、 最好仍是使用面向對象來編程。猴子補丁模式雖靈活,猴子補丁是在以前擴展沒設計好的基礎上纔不得已爲之才使用的。用起來不少弊端,好比pycharm智能提示和跳轉支持不好,由於是在運行時後改變行爲的,pycahrm是死的只會根據固定的代碼結構進行智能提示和補全,不會去猜想運行時候的行爲。模塊始終是個單例,一下子想var_aaa初始變量是3一會但願他是2,一會但願function_bbb的功能是擴大一百倍一下子但願他是擴大一萬倍,猴子補丁是沒法實現得,使用面oop這些問題是很是輕鬆很是正常天然的完成的,徹底不須要想。由於類能夠繼承,模塊沒法繼承;類是多實例的(每一個實例就像無數複製出來的內部屬性互不干擾的模塊),不會像模塊同樣只有一份。
五、本身寫的代碼最好設計好擴展使用oop,不要讓本身的模塊有被別人打猴子補丁的想法和機會。讓打猴子補丁只發生在修改三方包和官方包的時候,若是本身寫的代碼也須要大猴子補丁才能實現改造,那應該是沒設計好,沒有暴露出使用策略/模板方法。
六、關於面向過程和麪向對象編程,介紹了不少次區別,和oop的優勢。我絕對沒說過全部場景全部地方都要全100%使用純oop,但我反對那些無論任何狀況都堅持代碼只有0個類的寫法,這種寫法狀況的人現實和網上見過不少。多試下多對比下才能知道體會到區別,否則總是籠統的二逼的說法就是大項目用oop小項目用ofp當擋箭牌。具體多大才算大?200行代碼不算大嗎,每次新作項目功能時候把本身的200行代碼複製黏貼扣字修改反覆弄幾百次也算200行嗎?大項目也不可能純100%oop,會兩樣都有。
要知道何時使用oop,而不是數代碼的行數再來決定使不使用oop,好比8種方法實現寫計數器例子,實現計數器總共纔不到10行,寫閉包函數明顯比使用類更晦澀難懂,難道行數少就適合函數嗎?大項目也不是全部函數都須要改爲方法包裹在類裏面。
究竟是用哪種,一個判斷是函數若是是很是孤立的,不依賴外部狀態和依賴的外部函數不可能須要改變,好比單獨作個時間格式轉換,用函數沒毛病,放在大項目也能夠。
若是函數有一些依賴,特別是依賴的屬性和函數須要彈性改變,使用類好。
據個人實踐,我使用oop改造了項目裏面的不少模塊或者子任務,基本上每次使用oop重構都可以比原有的opp代碼減小40%-90%的代碼行數。