日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
為什么Python不用設(shè)計(jì)模式?

 在遙遠(yuǎn)的Python王國(guó),有一位少年,非常熱愛(ài)編程,他的父母想給他報(bào)一個(gè)班,問(wèn)了***的朋友圈以后,發(fā)現(xiàn)大家都推薦同一個(gè)老師,人稱(chēng)吉先生。

于是他的父母毫不猶豫就交了一筆不菲的學(xué)費(fèi),每周六日下午讓孩子去學(xué)習(xí)。

少年學(xué)習(xí)非??炭啵芸炀蛯W(xué)會(huì)了Python語(yǔ)法、工具和框架。

老師像是見(jiàn)到了可以雕刻的美玉, 傾囊相授,告訴他不僅要把代碼寫(xiě)對(duì),還要讓代碼漂亮、優(yōu)雅、可讀、可維護(hù)。

少年又學(xué)會(huì)了單元測(cè)試,TDD,重構(gòu),努力讓自己的代碼達(dá)到老師所要求的標(biāo)準(zhǔn)。

他還把“Python 之禪”貼在了自己的墻上,經(jīng)常對(duì)照自己的代碼,從來(lái)都不敢違反。

  • 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),無(wú)論他怎么努力,他的代碼都是亂糟糟的,沒(méi)有美感,他所寫(xiě)出的類(lèi),模塊混成了一團(tuán)。

于是他只好去請(qǐng)教老師: “老師,我的Python和Flask框架已經(jīng)用得滾瓜爛熟了,為什么完成不了這個(gè)項(xiàng)目呢?”

老師說(shuō):“孩子,原來(lái)你只需要把框架的類(lèi)給import進(jìn)來(lái),稍微寫(xiě)點(diǎn)兒代碼就行了,現(xiàn)在你需要自己去設(shè)計(jì)類(lèi),自己去做出抽象了!”

“怎么設(shè)計(jì)呢?”

“為師送你一本古書(shū),《設(shè)計(jì)模式》 ,你回去好好看看吧。”

少年如獲至寶, 廢寢忘食地去研究這本20多年前出的、泛黃的古書(shū),還是用C++描述的。

他看得云里霧里,似乎明白,又似乎不明白,只好再去請(qǐng)教老師。

這一次,老師給了他另外一本書(shū), 《Head First 設(shè)計(jì)模式》

少年翻開(kāi)一看,這本書(shū)是用Java寫(xiě)的,于是又一頭扎到了Java語(yǔ)言當(dāng)中。

這本書(shū)比較通俗易懂,少年看得大呼過(guò)癮。

終于,他信心十足地用Python開(kāi)始那個(gè)大項(xiàng)目了。

他用Python語(yǔ)言實(shí)現(xiàn)設(shè)計(jì)模式,解決一些設(shè)計(jì)問(wèn)題,可是總覺(jué)得不對(duì)勁,和Java , C++相比,感覺(jué)怪怪的。

另外他感覺(jué)到了動(dòng)態(tài)語(yǔ)言的不爽之處,每次想重構(gòu)的時(shí)候,總是不敢下手,他把困惑給老師說(shuō)了。

老師笑道:“我在Java王國(guó)的時(shí)候,人們總是說(shuō)‘動(dòng)態(tài)一時(shí)爽,重構(gòu)火葬場(chǎng)’, 現(xiàn)在你體會(huì)到了吧!”

“Java就能避免這個(gè)問(wèn)題嗎?”

“Java是一門(mén)靜態(tài)語(yǔ)言,變量類(lèi)型一旦確定就不能改變,對(duì)重構(gòu)的支持非常好,你有沒(méi)有興趣去看看?那里有很多的框架,像Spring,Spring Boot,MyBatis, Dubbo, Netty,非常繁榮發(fā)達(dá)?!?/p>

少年心生向往,于是老師就給他寫(xiě)了個(gè)條子,告訴他說(shuō)到了Java王國(guó),找到IO大臣,一切事情都會(huì)暢通無(wú)阻。

少年辭別老師,奔向了Java帝國(guó),老師整了整衣冠, 望著東方Java帝國(guó)的方向,莊嚴(yán)地拜了三拜:“五年了,IO大人,我沒(méi)有辜負(fù)您的重托,又忽悠了一個(gè)人去做Java了!”

原來(lái)這位老師就是吉森! IO大臣派來(lái)傳播Java文化和價(jià)值觀的傳教士,入境后不幸被識(shí)破,軟禁在了Python王國(guó)。

吉森的故事請(qǐng)移步《Java帝國(guó)對(duì)Python的滲透能成功嗎?》

Python沒(méi)有接口?

Python國(guó)王收到邊關(guān)的奏報(bào),說(shuō)是最近有不少年輕人奔向了Java王國(guó),不知道是不是國(guó)內(nèi)政策有變,導(dǎo)致人心浮動(dòng)。

Python國(guó)王震怒,下令嚴(yán)查。 查來(lái)查去,所有的線索都指向了一個(gè)人:吉森。

這一天,Python特使帶著士兵來(lái)到了吉森的住所,果然發(fā)現(xiàn)他又在忽悠年輕人了。

特使又氣又笑:“你學(xué)了半吊子的Python,居然敢來(lái)蠱惑人心,實(shí)在是可笑。”

吉森看到自己的計(jì)謀已被識(shí)破,依然很鎮(zhèn)靜:“大人誤會(huì)了,我教的就是正宗的面向?qū)ο蟮脑O(shè)計(jì)和設(shè)計(jì)模式啊,這設(shè)計(jì)模式用Python實(shí)現(xiàn)起來(lái)很別扭,我就推薦他們?nèi)W(xué)Java啊。”

“胡說(shuō),Python寫(xiě)設(shè)計(jì)模式怎么會(huì)很別扭? Java 由于語(yǔ)法所限,表達(dá)能力比較弱,對(duì)于一些問(wèn)題,只好用笨拙的設(shè)計(jì)模式來(lái)解決,我們Python有可能在語(yǔ)法層面就解決問(wèn)題了!”

“那你說(shuō)說(shuō),設(shè)計(jì)模式的原則是什么?” 吉森問(wèn)道。

“1. 面向接口編程,而不是面向?qū)崿F(xiàn)編程。2. 優(yōu)先使用組合而不是繼承?!?這是難不住特使的。

“Python連接口都沒(méi)有,怎么面向接口編程?” 吉森問(wèn)道。

特使哈哈大笑:“說(shuō)你是半吊子吧,你還不服,你以為這里的接口就是你們Java的interface啊!你忘了Python的Duck Typing了?”

 
 
 
 
  1. class Duck:
  2.     def fly(self):
  3.         print("Duck flying")
  4. class Airplane:
  5.     def fly(self):
  6.         print("Airplane flying")
  7. def lift_off(entity):
  8.     entity.fly()
  9. duck = Duck()
  10. plane = Airplane()
  11. lift_off(duck)
  12. lift_off(plane)

“看到?jīng)]有, Duck和Airplane都沒(méi)有實(shí)現(xiàn)你所謂的接口,但是都可以調(diào)用fly()方法,這難道不是面向接口編程, 如果你非要類(lèi)比的話(huà),這個(gè)fly就是一個(gè)自動(dòng)化的接口啊?!?/p>

吉森確實(shí)沒(méi)想到這一層,至于第二個(gè)原則,優(yōu)先使用組合而不是繼承,可以是每個(gè)面向?qū)ο蟮恼Z(yǔ)言都可以實(shí)現(xiàn)的,他嘆了口氣,也就不問(wèn)了。

Adapter模式

特使接著說(shuō):“Duck Typing非常強(qiáng)大,你不是提到了設(shè)計(jì)模式嗎,在Duck Typing面前,很多設(shè)計(jì)模式純屬多此一舉。我來(lái)給你舉個(gè)例子,Adapter模式。假設(shè)客戶(hù)端有這么一段代碼,可以把一段日志寫(xiě)入文件當(dāng)中?!?/p>

 
 
 
 
  1. def log(file,msg):
  2.     file.write('[{}] - {}'.format(datetime.now(), msg))

“現(xiàn)在來(lái)了新的需求,要把日志寫(xiě)入數(shù)據(jù)庫(kù), 而數(shù)據(jù)庫(kù)并沒(méi)有write 方法,怎么辦? 那就寫(xiě)個(gè)Adapter吧?!?/p>

 
 
 
 
  1. class DBAdapter:
  2.     def __init__(self, db):
  3.         self.db = db
  4.     def write(self, msg):
  5.         self.db.insert(msg)

“注意這個(gè)DBAdapter并不需要實(shí)現(xiàn)什么接口(我大Python也沒(méi)有接口),就是一個(gè)單獨(dú)的類(lèi),只需要有個(gè)write方法就可以了?!?/p>

 
 
 
 
  1. db_adapter = DBAdapter(db)
  2. log(db_adapter, "sev1 error occurred")

確實(shí)是很簡(jiǎn)單,只要有write 方法, 不管你是任何對(duì)象,都可以進(jìn)行調(diào)用, 典型的Duck Typing 。

既然Adapter可以這么寫(xiě),那Proxy模式也是類(lèi)似了,只要你的Proxy類(lèi)和被代理的類(lèi)的方法一樣,那就可以被客戶(hù)使用。

但是這種方法的弊端就是,不知道log方法的參數(shù)類(lèi)型,想要重構(gòu)可就難了。

單例模式

吉森又想到了一個(gè)問(wèn)題,繼續(xù)挑戰(zhàn)特使:“Python連個(gè)private 關(guān)鍵字都沒(méi)有,怎么隱藏一個(gè)類(lèi)的構(gòu)造函數(shù),怎么去實(shí)現(xiàn)單例?”

特使不屑地說(shuō):“忘掉你那套Java思維吧,在Python中想寫(xiě)個(gè)singleton有很多辦法,我給你展示一個(gè)比較Python的方式,用module的方式來(lái)實(shí)現(xiàn)。”

 
 
 
 
  1. #singleton.py
  2. class Singleton:
  3.     def __init__(self):
  4.         self.name = "i'm singleton"
  5. instance = Singleton()
  6. del Singleton  # 把構(gòu)造函數(shù)刪除

使用Singleton:

 
 
 
 
  1. import singleton
  2. print(singleton.instance.name)  # i'm singleton
  3. instance = Singleton() # NameError: name 'Singleton' is not defined

吉森確實(shí)沒(méi)有想到這種寫(xiě)法,利用Python的module來(lái)實(shí)現(xiàn)信息的隱藏。

Visitor模式

不是每個(gè)設(shè)計(jì)模式都能這么干吧? 吉森心中暗想,他腦海中浮現(xiàn)了一個(gè)難于理解的模式:Visitor,自己當(dāng)初為了學(xué)習(xí)它可是下了苦工。

吉森說(shuō):“那你說(shuō)說(shuō),對(duì)于Visitor,怎么利用Python的特色?”

“我知道你心里想的是什么,無(wú)非就是想讓我寫(xiě)一個(gè)類(lèi),然后在寫(xiě)個(gè)Visitor對(duì)它進(jìn)行訪問(wèn),是不是?”

 
 
 
 
  1. class TreeNode:
  2.     def __init__(self, data):
  3.         self.data = data
  4.         self.left = None
  5.         self.right = None
  6.     def accept(self, visitor):
  7.         if self.left is not None:
  8.             self.left.accept(visitor)
  9.         visitor.visit(self)
  10.         if self.right is not None:
  11.             self.right.accept(visitor)
  12. class PrintVisitor:
  13.     def visit(self,node):
  14.         print(node.data)
  15. root = TreeNode('1')
  16. root.left = TreeNode('2')
  17. root.right = TreeNode('3')
  18. visitor = PrintVisitor()
  19. root.accept(visitor)   #輸出2, 1, 3

吉森說(shuō):“是啊, 難道Visitor模式不是這么寫(xiě)的嗎? ”

"我就說(shuō)你的Python只是學(xué)了點(diǎn)皮毛吧,Visitor的本質(zhì)是在分離結(jié)構(gòu)和操作, 在Python中使用generator可以更加優(yōu)雅地實(shí)現(xiàn)?!?/p>

 
 
 
 
  1. class TreeNode:
  2.     def __iter__(self):
  3.         return self.__generator()
  4.     def __generator(self):
  5.         if self.left is not None:
  6.             yield from iter(self.left) 
  7.         yield from self.data
  8.         if self.right is not None:
  9.             yield from iter(self.right) 
  10. root = TreeNode('1')
  11. root.left = TreeNode('2')
  12. root.right = TreeNode('3')
  13. for ele in root:
  14.     print(ele)

不得不承認(rèn),這種方式使用起來(lái)更加簡(jiǎn)潔,同時(shí)達(dá)到了結(jié)構(gòu)和操作進(jìn)行分離的目的。

特使說(shuō)道: “看到了吧,Python在語(yǔ)言層面對(duì)一些模式提供了支持,所以很多設(shè)計(jì)模式在我大Python看起來(lái)非常笨拙,我們這里并不提倡,當(dāng)然我們還是要掌握面向?qū)ο笤O(shè)計(jì)的原則SOLID和設(shè)計(jì)模式的思想,發(fā)現(xiàn)變化并且封裝變化,這樣才能寫(xiě)出優(yōu)雅的程序出來(lái)。”

吉森嘆了一口氣,感慨自己學(xué)藝不精,不再反抗,束手就擒。

尾聲

Python王國(guó)審判了吉森,本來(lái)要判他死刑,但是Java帝國(guó)重兵壓境,要求釋放,否則就開(kāi)戰(zhàn)。

吉森被送回Java王國(guó),成為了人們心目中的英雄,回家他仔細(xì)對(duì)比了Java和Python,在Java虛擬機(jī)上把Python語(yǔ)言給實(shí)現(xiàn)了!國(guó)王為了表彰他的英勇事跡,把這個(gè)語(yǔ)言叫做Jython。

【本文為專(zhuān)欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)作者微信公眾號(hào)coderising獲取授權(quán)】


新聞標(biāo)題:為什么Python不用設(shè)計(jì)模式?
當(dāng)前地址:http://www.dlmjj.cn/article/djddjoe.html