?
在遙遠(yuǎn)的Python王國,有一位少年,非常熱愛編程,他的父母想給他報(bào)一個(gè)班,問了萬能的朋友圈以后,發(fā)現(xiàn)大家都推薦同一個(gè)老師,人稱吉先生。
于是他的父母毫不猶豫就交了一筆不菲的學(xué)費(fèi),每周六日下午讓孩子去學(xué)習(xí)。
少年學(xué)習(xí)非常刻苦,很快就學(xué)會(huì)了Python語法、工具和框架。
老師像是見到了可以雕刻的美玉,傾囊相授,告 訴他不僅要把代碼寫對,還要讓代碼漂亮、優(yōu)雅、可讀、可維護(hù)。
少年又學(xué)會(huì)了單元測試、TDD、重構(gòu),努力讓自己的代碼達(dá)到老師所要求的標(biāo)準(zhǔn)。
他還把“Python 之禪”貼在了自己的墻上,經(jīng)常對照自己的代碼,從來都不敢違反。
The Zen of Python, by Tim Peters
Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. ......
三年以后,少年以為自己成為了Python的大師,直到有一天,老師給他布置了一個(gè)大作業(yè),其實(shí)是個(gè)大項(xiàng)目,業(yè)務(wù)非常復(fù)雜。
少年通宵達(dá)旦地編程,可他悲慘地發(fā)現(xiàn),無論他怎么努力,他的代碼都是亂糟糟的,沒有美感,他所寫出的類,模塊混成了一團(tuán)。
于是他只好去請教老師: “老師,我的Python和Flask框架已經(jīng)用得滾瓜爛熟了,為什么完成不了這個(gè)項(xiàng)目呢?”
老師說:“孩子,原來你只需要把框架的類給import進(jìn)來,稍微寫點(diǎn)兒代碼就行了,現(xiàn)在你需要自己去設(shè)計(jì)類,自己去做出抽象了!”
“怎么設(shè)計(jì)呢?”
“為師送你一本古書《設(shè)計(jì)模式》,你回去好好看看吧。”
少年如獲至寶, 廢寢忘食地去研究這本20多年前出的、泛黃的古書,還是用C++描述的。
他看得云里霧里,似乎明白,又似乎不明白,只好再去請教老師。
這一次,老師給了他另外一本書《Head First 設(shè)計(jì)模式》。少年翻開一看,這本書是用Java寫的,于是又一頭扎到了Java語言當(dāng)中。
這本書比較通俗易懂,少年看得大呼過癮。
終于,他信心十足地用Python開始那個(gè)大項(xiàng)目了。
他用Python語言實(shí)現(xiàn)設(shè)計(jì)模式,解決一些設(shè)計(jì)問題,可是總覺得不對勁,和Java 、C++相比,感覺怪怪的。
另外他感覺到了動(dòng)態(tài)語言的不爽之處,每次想重構(gòu)的時(shí)候,總是不敢下手,他把困惑給老師說了。
老師笑道:“我在Java王國的時(shí)候,人們總是說‘動(dòng)態(tài)一時(shí)爽,重構(gòu)火葬場’, 現(xiàn)在你體會(huì)到了吧!”
“Java就能避免這個(gè)問題嗎?”
“Java是一門靜態(tài)語言,變量類型一旦確定就不能改變,對重構(gòu)的支持非常好,你有沒有興趣去看看?那里有很多的框架,像Spring、Spring Boot、MyBatis、Dubbo、Netty,非常繁榮發(fā)達(dá)。”
少年心生向往,于是老師就給他寫了個(gè)條子,告訴他說到了Java王國,找到IO大臣,一切事情都會(huì)暢通無阻。
少年辭別老師,奔向了Java帝國,老師整了整衣冠, 望著東方Java帝國的方向,莊嚴(yán)地拜了三拜:“五年了,IO大人,我沒有辜負(fù)您的重托,又忽悠了一個(gè)人去做Java了!”
原來這位老師就是吉森! IO大臣派來傳播Java文化和價(jià)值觀的傳教士,入境后不幸被識破,軟禁在了Python王國。
Python沒有接口?
Python國王收到邊關(guān)的奏報(bào),說是最近有不少年輕人奔向了Java王國,不知道是不是國內(nèi)政策有變,導(dǎo)致人心浮動(dòng)。
Python國王震怒,下令嚴(yán)查。 查來查去,所有的線索都指向了一個(gè)人:吉森。
這一天,Python特使帶著士兵來到了吉森的住所,果然發(fā)現(xiàn)他又在忽悠年輕人了。
特使又氣又笑:“你學(xué)了半吊子的Python,居然敢來蠱惑人心,實(shí)在是可笑。”
吉森看到自己的計(jì)謀已被識破,依然很鎮(zhèn)靜:“大人誤會(huì)了,我教的就是正宗的面向?qū)ο蟮脑O(shè)計(jì)和設(shè)計(jì)模式啊,這設(shè)計(jì)模式用Python實(shí)現(xiàn)起來很別扭,我就推薦他們?nèi)W(xué)Java啊。”
“胡說,Python寫設(shè)計(jì)模式怎么會(huì)很別扭? Java 由于語法所限,表達(dá)能力比較弱,對于一些問題,只好用笨拙的設(shè)計(jì)模式來解決,我們Python有可能在語法層面就解決問題了!”
“那你說說,設(shè)計(jì)模式的原則是什么?” 吉森問道。
“ 1. 面向接口編程,而不是面向?qū)崿F(xiàn)編程。2. 優(yōu)先使用組合而不是繼承。 ” 這是難不住特使的。
“Python連接口都沒有,怎么面向接口編程?” 吉森問道。
特使哈哈大笑:“說你是半吊子吧,你還不服,你以為這里的接口就是你們Java的interface啊!你忘了Python的 Duck Typing 了?”
?
)
“看到?jīng)]有, Duck和Airplane都沒有實(shí)現(xiàn)你所謂的接口,但是都可以調(diào)用fly()方法,這難道不是面向接口編程, 如果你非要類比的話,這個(gè)fly就是一個(gè)自動(dòng)化的接口啊。”
吉森確實(shí)沒想到這一層,至于第二個(gè)原則,優(yōu)先使用組合而不是繼承,可以是每個(gè)面向?qū)ο蟮恼Z言都可以實(shí)現(xiàn)的,他嘆了口氣,也就不問了。
?
一、Adapter模式
特使接著說:“Duck Typing非常強(qiáng)大,你不是提到了設(shè)計(jì)模式嗎,在Duck Typing面前,很多設(shè)計(jì)模式純屬多此一舉。我來給你舉個(gè)例子,Adapter模式。假設(shè)客戶端有這么一段代碼,可以把一段日志寫入文件當(dāng)中。”
?
?
“現(xiàn)在來了新的需求,要把日志寫入數(shù)據(jù)庫, 而數(shù)據(jù)庫并沒有write 方法,怎么辦? 那就寫個(gè)Adapter吧。”
?
?
“注意這個(gè)DBAdapter并不需要實(shí)現(xiàn)什么接口(我大Python也沒有接口),就是一個(gè)單獨(dú)的類,只需要有個(gè)write方法就可以了。”
?
?
確實(shí)是很簡單,只要有write 方法, 不管你是任何對象,都可以進(jìn)行調(diào)用, 典型的Duck Typing 。
既然Adapter可以這么寫,那Proxy模式也是類似了,只要你的Proxy類和被代理的類的方法一樣,那就可以被客戶使用。
但是這種方法的弊端就是,不知道log方法的參數(shù)類型,想要重構(gòu)可就難了。
?
2、單例模式
?
吉森又想到了一個(gè)問題,繼續(xù)挑戰(zhàn)特使:“Python連個(gè)private 關(guān)鍵字都沒有,怎么隱藏一個(gè)類的構(gòu)造函數(shù),怎么去實(shí)現(xiàn)單例?”
特使不屑地說:“忘掉你那套Java思維吧,在Python中想寫個(gè)Singleton有很多辦法,我給你展示一個(gè)比較Python的方式,用module的方式來實(shí)現(xiàn)。”
?
?
使用Singleton:
?
?
吉森確實(shí)沒有想到這種寫法,利用Python的module來實(shí)現(xiàn)信息的隱藏。
?
三、Visitor模式
?
不是每個(gè)設(shè)計(jì)模式都能這么干吧? 吉森心中暗想,他腦海中浮現(xiàn)了一個(gè)難于理解的模式:Visitor,自己當(dāng)初為了學(xué)習(xí)它可是下了苦工。
吉森說:“那你說說,對于Visitor,怎么利用Python的特色?”
“我知道你心里想的是什么,無非就是想讓我寫一個(gè)類,然后在寫個(gè)Visitor對它進(jìn)行訪問,是不是?”
?
?
吉森說:“是啊, 難道Visitor模式不是這么寫的嗎? ”
"我就說你的Python只是學(xué)了點(diǎn)皮毛吧,Visitor的本質(zhì)是在分離結(jié)構(gòu)和操作, 在Python中使用 generator 可以更加優(yōu)雅地實(shí)現(xiàn)。”
?
?
不得不承認(rèn),這種方式使用起來更加簡潔,同時(shí)達(dá)到了結(jié)構(gòu)和操作進(jìn)行分離的目的。
特使說道: “看到了吧,Python在語言層面對一些模式提供了支持,所以很多設(shè)計(jì)模式在我大Python看起來非常笨拙,我們這里并不提倡,當(dāng)然我們還是要掌握面向?qū)ο笤O(shè)計(jì)的原則SOLID和設(shè)計(jì)模式的思想,發(fā)現(xiàn)變化并且封裝變化,這樣才能寫出優(yōu)雅的程序出來。”
吉森嘆了一口氣,感慨自己學(xué)藝不精,不再反抗,束手就擒。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
