設計模式總結(《Head First設計模式》學習總結)

寫在前面:html

學習過程當中不只要熟練掌握技能,理論的消化吸取也必不可少。雖然我的更傾向於學習技術類的東西(短期的精力投入很快就能看到成效...),但看了不少前輩的經驗總結後才知道理論性的東西是絕對不能忽視的,畢竟理論對實踐有着重要的指導意義。而瞭解「設計」相關的東西,會對「實現」產生潛移默化的影響,雖然不能在短期內看到讓人欣喜的變化,但可能有一天回過頭來一想「哦~,原來我這個不錯的小習慣是當年在那本書上學到的啊」正則表達式

一.什麼是設計模式?算法

繞了一圈以後讓咱們又回到這個話題吧(看書以前問本身一遍,看完以後再問本身一遍,答案之間的差別就是感悟了)數據庫

以前:編程

自問:設計模式是什麼?設計模式

自答:是一些系統設計的指導原則吧,不過我如今每天寫代碼,應該也用不到設計層面上的東西。框架

自問:哦,那具體是什麼?學習

自答:不清楚,不過我見過一些前輩的代碼,結構很複雜,一看就很上檔次的那種,那些應該就用了設計模式吧,因此代碼有沒有應用設計模式應該就是高手與新手的區別了。等我成了高手以後,這種東西還不信手拈來,嗯,不說了,我寫代碼去了,好好積累項目經驗。優化

...ui

以後:

自問:設計模式是什麼?

自答:設計模式是由代碼結構優化經驗萃取出來的理論知識,應用成熟的設計模式可以加強代碼的可複用性、可擴展性與可維護性。

自問:你好像很專業的樣子,那好,既然設計模式有這麼多好處,那是否是應用了設計模式的設計都是好設計?

自答:固然不是,咱們不能爲了使用模式而使用模式。設計模式可不能濫用,畢竟應用設計模式必需要做出一些犧牲(好比增長類結構的複雜性...),因此濫用設計模式的話是會出事的。並且,就算咱們有了錘子,也不能把全部問題都看做釘子吧?

...

P.S.還記得學習正則表達式的總結:能不用就儘可能不要用(最大限度的避免濫用),設計模式與之相似,不能看到什麼問題都往模式上靠,只有當咱們很是肯定在當前情景下確實須要用設計模式來優化咱們的設計時,才考慮使用設計模式(至於到底用不用,還要權衡重構的成本與優化的收益...)

二.要不要使用設計模式?

這是個值得思考的問題,畢竟如今咱們已經擁有了一把錘子,要不要用它固然成了問題,畢竟不是全部的問題均可以用錘子來解決。退一步講,即使全部問題都能用錘子解決,咱們也不肯定使用錘子是否是最好的解決方案(拔釘子的話,可能用鉗子更好些...)

當咱們拿着某個設計模式想放進咱們的代碼中時,最好權衡一下利弊,誠然,設計模式具備的設計上的彈性必定會給咱們以後的維護變動帶來些便利。可是利與弊到底哪一個更多一些,咱們須要先回答幾個問題再作決定:

  • 咱們的項目是否是幾乎不涉及維護或者沒有後續版本,那麼咱們引入設計模式還有必要嗎?
  • 咱們項目的規模是否是大到了不用設計模式不行的地步?
  • 這個設計模式用在這裏合適嗎?有沒有更合適的?
  • 非要用設計模式嗎?可不能夠用幾個簡單的設計原則來代替?
  • 引入設計模式以後,代碼結構的複雜度大大增長,重構的成本咱們能夠接受嗎?

若是深思熟慮以後,仍是以爲使用設計模式比較好,那麼,放心去用吧,以後好好享受設計模式帶來的好處吧

三.設計原則總結

設計原則都是一些簡單的指導意見,沒有固定的實現,於是設計原則也更加靈活,常見的設計原則以下:

  1. 封裝變化(把易於發生變化的部分抽出來,以減小其變化對其它部分的影響)
  2. 多用組合,少用繼承(組合比繼承更有彈性)
  3. 針對接口編程,不針對實現編程(使用接口能夠避免直接依賴具體類)
  4. 爲交互對象之間的鬆耦合設計而努力(更鬆的耦合意味着更多的彈性)
  5. 類應該對擴展開放,對修改關閉(open-close原則)
  6. 依賴抽象,不要依賴具體類(減小對具體類的直接依賴)
  7. 只和朋友交談(密友原則)
  8. 別找我,我會找你(Don't call me, I will call you back.安卓開發的大原則)
  9. 類應該只有一個改變的理由(單一責任原則)

能用設計原則解決的問題就不要用設計模式(殺雞焉用宰牛刀...),由於設計原則實現起來更加靈活,更加輕巧(不用去考慮模式的條條框框...)

四.設計模式總結

名稱 特色
策略模式(Strategy) 把能夠替換的算法步驟封裝成一個個算法族,供運行時動態選擇
觀察者模式(Observer) 定義並維護對象之間的一對多關係
裝飾者模式(Decorator) 創建擁有共同超類的裝飾者與被裝飾者來實現功能的動態擴展
工廠模式(Factory) 封裝對象的建立過程,包括工廠方法模式和抽象工廠模式
單件(例)模式(Singleton) 用來建立惟一的對象(好比數據庫鏈接對象,線程池對象等等)
命令模式(Command) 封裝方法調用細節,解耦請求者與執行者
適配器模式(Adapter) 用來實現不一樣接口間的轉換
外觀模式(Facade) 爲複雜的子系統提供簡單易用的高層接口
模版方法模式(Template Method) 用來封裝算法骨架(流程),某些步驟由子類實現
迭代器模式(Iterator) 用來封裝遍歷細節
組合模式(Composite) 提供一種層級結構,使得咱們可以忽略對象與對象集合間的差別,一視同仁地對待它們
狀態模式(State) 把全部動做都封裝在狀態對象中,狀態持有者將行爲委託給當前狀態對象
代理模式(Proxy) 經過插入第三方(代理對象)來分離調用者和被調用者(不一樣於執行者)
複合模式(Compound) 將多個模式組合結合起來造成一個「框架」,以解決通常性問題
橋接模式(Bridge) 將抽象的控制類與具體實現類經過組合解耦,使得抽象層類與實現層類能夠對立與對方而變化
生成器模式(Builder) 用來封裝組合結構(樹形結構)的構造過程,與迭代器模式相似,都隱藏了組合結構的內部實現,只提供一組用於建立組合結構的接口
責任鏈模式(Chain of Responsibility) 讓一個請求能夠被一組接收者順序處理,相似於Android處理請求的方式:一個接收者捕獲請求後能夠return true消費掉請求,也能夠return false傳遞給接收者隊列中的下一個接收者(觀察者)
蠅量模式(Flyweight) 抽象出對象管理層來統一管理大量的同類型對象,以減小運行時對象實例的個數,減小內存消耗
解釋器模式(Interpreter) 用來爲簡單語言建立解釋器,將語法規則直接映射爲各個類,結構簡單,但效率較低
中介者模式(Mediator) 引入中介者來封裝多個對象間的複雜交互,以下降同級(在類結構統一層次上的)對象間的依賴
備忘錄模式(Memento) 支持對象狀態的保存與恢復,並將對象狀態數據封裝起來,獨立於客戶代碼以提供保護(Java中能夠結合序列化反序列化技術來實現該模式)
原型模式(Prototype) 以現有的對象爲原型,經過clone獲得新的對象(以簡化新對象的建立過程)
訪問者模式(Visitor) 爲組合結構添加新的操做,而不須要頻繁的改變組合結構

 

五.面向對象的設計(Object Oriented Design)

一直伴隨着OOD的問題就是「折衷」(或者說是「取捨」),最簡單的例子——要不要用設計模式?

  • 用,意味着將產生複雜的類關係,多層的抽象,咱們將犧牲易讀性換取易擴展性、易維護性或者其它特性
  • 不用,意味着咱們不須要對現有代碼進行重構(或者不用去在複雜的設計上耗費過多的時間),但使用設計模式的全部好處咱們就都享受不到了

兩者選其一,這就是一個「取捨」,或者創造第三個選項(好比使用設計原則),這就是一個「折衷」

寫在後面:關於《Head First設計模式》

不多寫書評,由於每一個人的喜愛不一樣,很差做推薦(甚至有時候喜歡一本書僅僅是由於喜歡做者的行文風格而已,從而不自覺的認爲書籍內容不錯。。)

這本書是前輩推薦的,看完以後以爲大部分章節講的很不錯,既細緻又通俗,但感受某些章節並非很好(好比第一章策略模式的例子不很貼切,和後面的遠程代理部分細節展開的不合理)

整體來講,做爲入門書籍的話,《Head First設計模式》仍是不錯的,我的感覺,僅供參考

相關文章
相關標籤/搜索