設計模式(Design pattern)代表了最佳的實踐,通常被有經驗的面向對象的軟件開發人員所采用。設計模式是軟件開發人員在軟件開發過程中面臨的一般問題的解決方案。這些解決方案是眾多軟件開發人員經過相當長的一段時間的試驗和錯誤總結出來的。
設計模式一般是針對java語言而言,一般的主推面向過程的js 、shell、c語言就很少談那么多種套路了。通常說的設計模式也是從java經驗中提取出來的。
但只要是面向對象的語言,設計模式都可以融入,如php python,但腳本語言像python談論設計模式的場景和次數比java少很多,估計是py入門低,使用靈活,很多人只習慣喜歡opp方式編程,還有就是py人數在國內十分少,從招聘網站上基本可以得出結論,除開軟件測試領域、運維領域或者一些個體戶(這些用py只是輔助不是天天寫項目),正規軍python不到java php的二十分之一估計~~。
設計模式,必須是oop編程,如果寫代碼只喜歡從上往下一條條命令累加,或者是提取出一些函數來復用,排斥oop,那絕大多數的設計模式都是用不了了(可以給模塊打猴子補丁來實現,但是很坑很別扭的這種方式),所以90%的設計模式必須是oop方式的編程。
python中和java有點不同,py沒有接口(就比如工廠模式、外觀模式、橋接模式啥的啥的java需要保證多個類有同樣的方法,會使用接口,python本身沒有接口,三方包zope.interface里面可以實現接口,python只要保證那些類是鴨子類型就ok了,沒有強制性的接口,比較靈活,但約束少很難保證多個人合作時候懂這個意圖,強制實現接口和鴨子類各有利弊吧),py支持多繼承和mixin類甚至是打猴子補丁,不是需要完全與java一樣來寫。
如果沒聽說設計模式那也有可能經常用過某模式,或者靈感爆發用了某模式,只有專門學習設計模式,才能形成穩定的設計和輸出。也有認為設計模式不重要的不需要學習,說得是類似金庸風清揚境界的無招勝有招,手中無招,心中有招。設計模式沒有個死的,特別是設計模式的結構型模式中很多模式,基本通過類的組合千變萬化變幻而來,很相近的。但是成為編程界的風清揚估計沒個七八年的編程經驗和好悟性達不到,風清揚也是老了才那么厲害嘛,要想速成可學葵花寶典。風清揚也是先要按套路學,不學基礎就達不到這種境界,無招勝有招說的是不能死按套路來,見文。
主要還是有固定的模式,看代碼容易些。別人接盤也方便。因為遇到過很多人所有地方所有場景全寫函數,而且沒有下划線來區別哪些只是內部輔助函數,或者一個函數高達300行,真的很坑爹。如果不會自定義項目或者完全不懂設計模式,那應該找個三方框架來用,這樣接盤俠也容易看懂,因為你是按照標准的三方庫來用的,別人看代碼就節約很多時間了。又不引用三方框架 嚴格按框架的規定來寫,又不用設計模式,到處是原生自定義的寫的很長一坨一坨的函數,接盤這樣的代碼那就很煩人,需要不停的ctrl 加b跳轉代碼和上下翻屏查看函數怎么寫的。
據我的經驗改造了十幾個模塊,光是使用oop就能最起碼使代碼數量減少40到70%,如果配合設計模式,能夠使代碼數量最多減少高達90%。我說的這個優化量是針對無限 復制+ 黏貼 + 扣字 這種寫法的人寫出來的代碼,比如寫十幾個平台,每個平台又分國內外,差的人寫法是,無限復制粘貼一個寫好的文件然后扣字母去修改,因為每個平台又80%的共性,又有20%的不同之處,不會模式的人,會情不自禁很容易懶惰造成不想在設計模式層面下功夫而是無限制粘貼扣字的low逼寫法,寫到最后改一個問題,需要修改幾十個文件,每個文件高達600多行,改起來十分麻煩,容易出錯。
見金庸《笑傲江湖》第十章《傳劍》:死招數破得再妙,遇上了活招數,免不了縛手縛腳,
只有任人屠戮。這個‘活’字,你要牢牢記住了。學招時要活學,使招時要活使。倘若拘泥不化,
便練熟了幾千萬手絕招,遇上了真正高手,終究還是給人家破得干干凈凈。”令狐沖大喜,
他生性飛揚跳脫,風清揚這幾句話當真說到了他心坎里去,連稱:“是,是!須得活學活
使。”風清揚道:“五岳劍派中各有無數蠢才,以為將師父傳下來的劍招學得精熟,自然
而然便成高手,哼哼,熟讀唐詩三百首,不會作詩也會吟!熟讀了人家詩句,做幾首打油
詩是可以的,但若不能自出機抒,能成大詩人么?”他這番話,自然是連岳不群也罵在其
中了,但令狐沖一來覺得這話十分有理,二來他並未直提岳不群的名字,也就沒有抗辯。
風清揚道:“活學活使,只是第一步。要做到出手無招,那才真是踏入了高手的境界。你
說‘各招渾成,敵人便無法可破’,這句話還只說對了一小半。不是‘渾成’,而是根本
無招。你的劍招使得再渾成,只要有跡可尋,敵人便有隙可乘。但如你根本並無招式,敵
人如何來破你的招式?”令狐沖一顆心怦怦亂跳,手心發熱,喃喃的道:“根本無招,如
何可破?根本無招,如何可破?”斗然之間,眼前出現了一個生平從所未見、連做夢也想
不到的新天地。風清揚道:“要切肉,總得有肉可切;要斬柴,總得有柴可斬;敵人要破
你劍招,你須得有劍招給人家來破才成。一個從未學過武功的常人,拿了劍亂揮亂舞,你
見聞再博,也猜不到他下一劍要刺向哪里,砍向何處。就算是劍術至精之人,也破不了他
的招式,只因並無招式,‘破招’二字,便談不上了。只是不曾學過武功之人,雖無招式
,卻會給人輕而易舉的打倒。真正上乘的劍術,則是能制人而決不能為人所制。”他拾起
地下的一根死人腿骨,隨手以一端對着令狐沖,道:“你如何破我這一招?”
令狐沖不知他這一下是甚么招式,一怔之下,便道:“這不是招式,因此破解不得。
”
風清揚微微一笑,道:“這就是了。學武之人使兵刃,動拳腳,總是有招式的,你只
須知道破法,一出手便能破招制敵。”令狐沖道:“要是敵人也沒招式呢?”風清揚道:
“那么他也是一等一的高手了,二人打到如何便如何,說不定是你高些,也說不定是他高
些。”
有時候面向過程寫的東西真的很復雜的,又不好擴展,特別是交給別人維護時候,非常多的函數高達幾十個函數,到處在函數里面return和傳參,接盤的人真的很難讀懂代碼,會造成上班工作時候成心情很差。
例如五子棋,面向過程的設計思路就是首先分析問題的步驟:
1、開始游戲,
2、黑子先走,
3、繪制畫面,
4、判斷輸贏,
5、輪到白子,
6、繪制畫面,
7、判斷輸贏,
8、返回步驟2,
9、輸出最后結果。
把上面每個步驟用分別的函數來實現,問題就解決了。
而面向對象的設計則是從另外的思路來解決問題。整個五子棋可以分為:
1、黑白雙方,這兩方的行為是一模一樣的,
2、棋盤系統,負責繪制畫面,
3、規則系統,負責判定諸如犯規、輸贏等。
第一類對象(玩家對象)負責接受用戶輸入,並告知第二類對象(棋盤對象)棋子布局的變化,棋盤對象接收到了棋子的變化就要負責在屏幕上面顯示出這種變化,同時利用第三類對象(規則系統)來對棋局進行判定。
可 以明顯地看出,面向對象是以功能來划分問題,而不是步驟。同樣是繪制棋局,這樣的行為在面向過程的設計中分散在了總多步驟中,很可能出現不同的繪制版本, 因為通常設計人員會考慮到實際情況進行各種各樣的簡化。而面向對象的設計中,繪圖只可能在棋盤對象中出現,從而保證了繪圖的統一。
功 能上的統一保證了面向對象設計的可擴展性。比如我要加入悔棋的功能,如果要改動面向過程的設計,那么從輸入到判斷到顯示這一連串的步驟都要改動,甚至步驟 之間的循序都要進行大規模調整。如果是面向對象的話,只用改動棋盤對象就行了,棋盤系統保存了黑白雙方的棋譜,簡單回溯就可以了,而顯示和規則判斷則不用 顧及,同時整個對對象功能的調用順序都沒有變化,改動只是局部的。
python擴展類方面,大體包括繼承 組合 mixin三種。
繼承:子類繼承父類,子類具有父類的屬性和方法。子類還是和父類是同種東西。比如人和孩子、成年人,孩子也是屬於人。is A
組合:人和手機,人可以有一個實例屬性叫phone,phone的值則是一個Phone類的實例,這樣通過操作人這個對象的phone屬性來操作手機瀏覽網頁和打電話。具體的打電話和瀏覽網頁的功能在Phone類中,手機可以有打電話 發短信的功能,人本身不具備這個功能。在實例方法中操作手機是self.phone.send_mesage('你好'),而不要弄成人繼承手機,然后用self.send_mesage('你好'),人不是手機的子類,不要搞成繼承,人和手機的關系是has A。設計模式,大多是通過組合來變換出來的,繼承要少用,除非確定子類是父類的一個更小分類。例如界(Kingdom)、門(Phylum)、綱(Class)、目(Order)、科(Family)、屬(Genus)、種(Species),更小的分類是上一級父類的一個子集。
mixin: 擴展類的功能,插件類,男學生和女學生都可以繼承一個上課的mixin類,成年人可以繼承一個打工賺錢的mixin類。一般情況下mixin類不寫__init__方法,mixin類里面的有些屬性在mixin類本身中不具備,所以不可以把mixin類單獨直接的實例化。mixin方式可以被組合替代,mixin類的方法可以直接訪問基本類的方法和屬性,組合把基本類實例綁定到組合類的實例屬性或者把基本類實例作為參數傳給其方法,來達到訪問基本類的方法和屬性。使用場景有,多個類要添加相同的功能,可以去每個類寫幾個方法,多少個類復制黏貼多少次,重復較多,要修改的時候又要去每個類去修改。代碼太長命名空間下方法太多,類變成了上帝類。
mixin類例如:
class Person(): def __init__(self, name): self.name = name def walk(self): print '行走' class StudyMixin(): def study(self): print self.name + '...在上課...' class Student(Person,StudyMixin): def __init__(self, name,age): Person.__init__(self,name) self.age=age def eat(self): print self.name + '...在吃飯...' Student('小明',10).study() # StudyMixin().study()
這樣做小明本來繼承自person只能走路,但加了mixin類,小明可以學習了。StudyMixin類則不能直接實例化,因為在這個類中,沒有name這個屬性,運行study方法會出錯。
軟件工程中,設計模式是指軟件設計問題的推薦方案。設計模式一般是描述如何組織代碼和
使用最佳實踐來解決常見的設計問題。需謹記在心的一點是:設計模式是高層次的方案,並不關
注具體的實現細節,比如算法和數據結構
創建型模式:
設計模式 -創建型模式 ,工廠模式 、抽象工廠模式
設計模式- 創建型模式, 建造者模式
設計模式-創建型模式,原型模式
設計模式-創建型模式,python享元模式 、python單例模式
python對象池模式
結構型模式:
設計模式-創結構型模式,python 橋接模式
設計模式-結構型模式,適配器模式(4)
設計模式-結構型模式,python組合模式
裝飾器模式 http://www.cnblogs.com/ydf0509/p/8525692.html
外觀模式 http://www.cnblogs.com/ydf0509/p/8525853.html
mvc模式 http://www.cnblogs.com/ydf0509/p/8525949.html
代理模式 http://www.cnblogs.com/ydf0509/p/8525970.html
行為型模式:
責任鏈模式 http://www.cnblogs.com/ydf0509/p/8525991.html
命令模式 http://www.cnblogs.com/ydf0509/p/8526012.html
解釋器模式 http://www.cnblogs.com/ydf0509/p/8526064.html
觀察者模式 http://www.cnblogs.com/ydf0509/p/8526100.html
狀態模式 http://www.cnblogs.com/ydf0509/p/8527468.html
策略模式 http://www.cnblogs.com/ydf0509/p/8527515.html
模板模式 http://www.cnblogs.com/ydf0509/p/8527685.html
設計模式-行為型模式,python 中介者模式
設計模式-行為型模式,python備忘錄模式
設計模式-行為型模式,python訪問者模式
python 迭代器模式
python設計模式之猴子補丁模式 python獨有模式
為保證對模式沒有誤解和誤判,代碼例子是用的從精通python 16種設計模式那本書中的,有的用的網上的。
一個在線的 http://www.pythontip.com/pythonPatterns/
github的 https://github.com/faif/python-patterns
菜鳥教程的 http://www.runoob.com/design-pattern/design-pattern-tutorial.html