簡書 賈小強
轉(zhuǎn)載請注明原創(chuàng)出處饥瓷,謝謝伙狐!
在靜態(tài)語言比如Java中被人熟知的21種設(shè)計模式可以謂大名鼎鼎涮毫,而為什么到了動態(tài)語言比如Python中設(shè)計模式不再突出,這篇文章講進行分析
在靜態(tài)語言中為了不讓代碼寫死鳞骤,為可能的變化預(yù)留靈活性窒百,從而很多模式都利用接口,高層代碼面向抽象編程豫尽,只有當(dāng)實際運行的時候代碼高層代碼才執(zhí)行實例化的具體對象的方法,而在動態(tài)語言中語言本身就具有動態(tài)性顷帖,于是不再需要顯式的接口
靜態(tài)語言(Java) | 動態(tài)語言(Python) |
---|---|
優(yōu)點:由于顯式面向接口美旧,于是在IDE中可以跳轉(zhuǎn)到特定的接口渤滞,然后通過接口又可以找到實現(xiàn)這個接口的某些類,建立代碼的聯(lián)系更方便直觀 | 優(yōu)點:省事榴嗅,不需要顯式專門寫個接口妄呕。方便的高級數(shù)據(jù)結(jié)構(gòu)list,dict嗽测,set绪励,方便構(gòu)造json |
缺點:費事,需要更多的代碼唠粥,類型聲明疏魏,顯示接口定義。沒有方便的list晤愧,dict大莫,set,構(gòu)造json顯得臃腫官份,不自然 | 缺點:只有當(dāng)代碼實際運行的時候在知道某個變量到底是什么只厘,于是對某個方法,或者某個類在沒運行的情況下不容易理解 |
也許有人覺得面對復(fù)雜的代碼我們情愿多寫一點東西舅巷,讓代碼更加方便理解羔味,這確實不錯,那么動態(tài)語言是否真的寫不出強壯并且方便理解的代碼呢钠右?
實際情況并不是這樣介评,通過足夠的單元測試和模擬測試,針對每個類或者方法有對應(yīng)的單元測試爬舰,需要理解代碼们陆,只需要跑一下對應(yīng)的測試加上斷點也可以方便的理解某些變量實際上到底是個啥我們都知道單元測試如此重要,在靜態(tài)語言中一樣情屹,那么既然靜態(tài)語言也需要寫單元測試坪仇,那么靜態(tài)語言的顯示的接口是否多余呢?
從代碼理解的角度確實是這樣垃你,但是顯式接口有些是靜態(tài)語言所不具有的優(yōu)勢椅文,比如上面提到的IDE支持可以通過接口知道實現(xiàn)這個接口的有哪些類,在沒單元測試支撐的情況下惜颇,靜態(tài)語言更加容易理解學(xué)習(xí)擴展皆刺,比如知道某個類依賴某個類型的接口就可以學(xué)習(xí)相關(guān)的各種不同變體了,而動態(tài)語言中單元測試了解的只是局部凌摄,然后通過局部的類羡蛾,再去找到可能存在的繼承體系,動態(tài)語言知識相對沒有顯式的聯(lián)系锨亏,為此假設(shè)拿到一個類痴怨,再沒跑起來的情況下忙干,可能無法繼續(xù)學(xué)習(xí),當(dāng)然不能跑起來的代碼本身就沒有價值浪藻,代碼終是都能跑起來的靜態(tài)語言更方便夠構(gòu)建抽象層次更高的系統(tǒng)嗎捐迫?
在動態(tài)語言中,假設(shè)我們在一個高層考慮問題爱葵,編寫高層代碼的時候沒有IDE的自動提示施戴,只能依靠自己理解來建立聯(lián)系,需要人記住的更多和靠人主觀建立聯(lián)系萌丈,至少某個方法傳入的是個x赞哗,實際我在給一個Frame類型對象編程,那么沒代碼提示浓瞪,真心不方便懈玻。以此推論,靜態(tài)語言可以方便的在高層編碼乾颁,甚至層次不斷提升涂乌,而動態(tài)語言到了高層只有靠人,而且有的代碼重構(gòu)根本無法實現(xiàn)英岭,比如我想講x重命名湾盒,也只能重命名方法作用域的局部變量,并不能將整個項目中同種類型的對象重命名诅妹,可能在一個大型的項目中這將產(chǎn)生嚴(yán)重的悲劇罚勾,不同的team在用不同的名字表達(dá)同一個東西動態(tài)語言是不是不存在,或者不需要設(shè)計模式吭狡?
答案是否定的尖殃,首先對于有些設(shè)計模式,在動態(tài)語言中確實根本不需要划煮,但是對于一個設(shè)計良好的面向?qū)ο笙到y(tǒng)而言送丰,并不分動態(tài)還是靜態(tài)語言,至少如果某些數(shù)據(jù)和數(shù)據(jù)相關(guān)的操作沒在一起弛秋,分離兩地器躏,各種傳來傳去,很快動態(tài)語言將為方便付出代價蟹略,科學(xué)有效的面向?qū)ο蠓治鲈O(shè)計終是能夠帶來好處登失,而從本質(zhì)的角度理解,如果需要高層代碼和底層代碼分離挖炬,那么還是需要高層代碼面向隱式的接口編程揽浙。當(dāng)然這一些都是在逐漸復(fù)雜不可控的情況下,如果你的系統(tǒng)只是個HelloWorld,別提什么設(shè)計模式捏萍,設(shè)計模式是根據(jù)需要而生的實際的一般系統(tǒng)并沒有那多變化太抓,實際上面向抽象并沒有那么必須空闲?
答案是肯定的令杈,面向過程的C語言寫出了操作系統(tǒng),數(shù)據(jù)庫碴倾,各種厲害的軟件逗噩,設(shè)計模式甚至面向?qū)ο蠖疾⒉皇潜仨毜模鞣N設(shè)計模式中奇奇怪怪的抽象分割在沒必要的情況下只會給系統(tǒng)增加不必需要的復(fù)雜性跌榔,只有都衡量利弊根據(jù)需要后才有一個答案异雁,但是如果不知道,那恐怕只有一個解僧须,優(yōu)秀的程序員是一種寧愿思考1小時然后編碼的生物纲刀,而不是不加思考權(quán)衡封山開山封水開水,后終將陷入自己設(shè)計的泥潭担平,同時不從多種方案中選擇權(quán)衡的程序員也無法達(dá)到更高的高度
Happy learning !!