C++實現20個設計模式


原文轉自:http://c.chinaitlab.com/special/sjms/Index.html

可以參考:https://www.cnblogs.com/whiteyun/category/272006.html

一個月下來,把常見的20個設計模式好好復習並且逐個用C++實現了一遍,收獲還是很大的,很多東西看上去明白了但是真正動手去做的時候發現其實還是不明白--我深知這個道理,於是不敢怠慢,不敢寫什么所謂的解釋原理的偽代碼,不敢說所謂的"知道原理就可以了"....因為我知道,我還還沒有資格說這個話,至少對於設計模式而言我還是一個初學者,唯有踏實和實干才能慢慢的掌握到知識.

在我學習設計模式的過程中,覺得造成理解困難的主要是以下幾點,談一下自己的體會,希望對他人有幫助,不要走上我的老路上,畢竟我花了N長的時間才敢號稱自己入門了~~!!-_-:
1)Gof並不適合於初學者.初學設計模式的一般都是從Gof入門開始學習的,不幸的是,這不是一本好的教科書,而把這本書稱為一本奠定了設計模式理論基礎的開山之作也許好一些,它把這些散落在各個設計中的常見模式收集起來,從此開始有了一個名詞叫做"Design Pattern".說這本書不是一本好的教科書主要是以下的幾個原因:

a)對設計模式或者說面向對象里面的一些原則性的東西解釋的不夠多不夠徹底,比如"面向接口編程而不是對實現編程","優先采用組合而不是繼承"等等,以至於后面看到各個模式的實現的時候很多模式看起來很相似卻找不到區別和共性的地方.

b)對各個模式的解釋或者舉出來的例子不是特別的好,大部分都是為了講解模式而講解,沒有加入前面提到過的一些基本原則的考量在里面,也就是說:原理性的東西和實現(各個設計模式)脫節.

2)初學者對語言或者說一些概念理解的不好.拿C++來說,為了做到面向對象需要提供的語言上的支持有繼承,多態,封裝,虛函數,抽象等等,我以前初學C++的時候,只為了學這些概念而去學習,不知道為什么要提供這些特性,這也是造成我走彎路的重要原因之一.當然,指望一個初學者在初學語言的時候就知道why是一件很困難的事情,也許結合着對設計模式的理解可以幫助你消化這些概念(我就是這樣的).

3)看不懂UML結構圖和時序圖,UML圖解釋的類與類之間的關系,時序圖解釋的是各個對象的實現方式,兩者結合在一起看才能加深對設計模式的理解,事實上,我現在已經可以做到僅僅看這兩個圖示就掌握一個模式的原理和實現了.
4)寫的代碼和參與過的項目不夠多.設計模式和很多東西的產生過程都是一樣的,首先人們遇到了問題,然后很多人解決了這個問題,於是漸漸的有人出來總結出解決這些問題所要遵守的一些原理和常用方法(我們稱之為"模式"),久而久之就形成了一個理論或者說一個學科.而后人在講述這些理論的時候大都是照本宣科,這對於計算機這樣一個強調實踐的學科或者說對於設計模式這樣一個理論而言要理解起來是很困難的.前人在提出這些理論的時候一些考量,權衡等等只有在你自己遇到了這些問題的時候才能慢慢的體會.有一種說法是,沒有寫上10W行代碼不要空談什么設計模式大概就是這個意思吧.

綜上所述,造成初學者學習設計模式困難的原因,一個是對基本的原則理解的不夠透徹,一個的選的入門教材不合理,還有一個就是對各個模式的表述不明白,再次是實踐不夠多.有幾本書籍,我看過,我想可以談談我的看法.第一本,<<敏捷軟件開發:原則,模式與實踐>>,這本書對於設計模式最大的貢獻在於專門有幾個章節講述了面向對象的幾個原則,比如Likov原則,開放封閉原則等等的,這幾個章節在我學習設計模式的過程中起了關鍵的作用,因為當我理解了這些原則之后開始慢慢明白為什么要有純虛函數提供接口,為什么要

有抽象基類,為什么要封裝....我開始用這些原則去理解各個設計模式,開始慢慢體會各個模式的區別和共性.另外看過的兩本書,我覺得性質都一樣,如果你缺錢,任選其一吧.第一本是<<設計模式精解>>,第二本是<<深入淺出設計模式>>,都是我花上幾個晚上 就可以看完的書.這兩本的立足點都是以生動的例子結合面向對象的基本原理來講解模式,我更喜歡前者一些(后者太貴,要不是打5折我才不買吶:)其次,要多接觸項目或者可以找一些好的代碼來看看,自己也多寫一些代碼.基本上,只要是用面向對象的語言開發的項目,里面沒有幾個模式的運用是不可能的了.因此,要戒除那些一開始接觸設計模式就想整明白的幻想,因為要真正的理解需要很多的實踐,同樣的一時半會理解不了的也不必氣餒(GOF的E文版我看了好多遍了:),堅信自己多實踐一定可以慢慢的悟道的.關於設計模式的一個疑問:非面向對象語言中有沒有所謂的"設計模式"?設計模式最初的定義是解決一些問題的慣用方法(大意如此),並沒有明確的說必須要支持某種特性的語言.我用純C開發的項目實在是有限,平時也只是自己作一些小東西玩玩,沒有做過任何一個上萬行的純C開發的項目,所以一直對這個問題抱有疑問~~anyway,有問題是好事,說明我在思考~~把這個問題放在這里,以后慢慢實踐之琢磨之~~

 

 

 導航目錄
 ※ 設計模式解析和實現之一-Factory模式  ※ 設計模式解析和實現之八-Composite模式  ※ 設計模式解析和實現之十五-Observer模式
 ※ 設計模式解析和實現之二-AF模式  ※ 設計模式解析和實現之九-Decorator模式  ※ 設計模式解析和實現之十六-Strategy模式
 ※ 設計模式解析和實現之三-Builder模式  ※ 設計模式解析和實現之十-Proxy模式  ※ 設計模式解析和實現之十七-State模式
 ※ 設計模式解析和實現之四-Prototype模式  ※ 設計模式解析和實現之十一-TM模式  ※ 設計模式解析和實現之十八-Iterator模式
 ※ 設計模式解析和實現之五-Singleton模式  ※ 設計模式解析和實現之十二-COR模式  ※ 設計模式解析和實現之十九-Memento模式
 ※ 設計模式解析和實現之六-Adapt模式  ※ 設計模式解析和實現之十三-FlyWeight模式  ※ 設計模式解析和實現之二十-Visitor模式
 ※ 設計模式解析和實現之七-Bridge模式  ※ 設計模式解析和實現之十四-Command模式
 

 

 設計模式的解析和實現之一-Factory模式
作用:
  定義一個用於創建對象的接口,讓子類決定實例化哪一個類。Factory Method 使一個類的實例化延遲到其子類。
  UML結構圖:
 
抽象基類:
1)Product:創建出來的對象的抽象基類。
2)Factory創建對象的工廠方法的抽象基類。 [詳細內容]
 

 

 設計模式解析和實現之二-Abstract Factory模式
作用:
  提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
  UML結構圖:
點擊查看大圖
抽象基類:
1)ProductA,ProductB:分別代表不同類型的產品,而它們的派生類則是這種產品的一個實現。
2)AbstractFactory:生產這一系列產品的一個抽象工廠,它的派生類是不同的實現。 [詳細內容]
 

 

 設計模式的解析和實現之三-Builder模式
作用:
  將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
  UML結構圖:
點擊查看大圖
適用於以下情況:
1)當創建復雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。
2)當構造過程必須允許被構造的對象有不同的表示時。 [詳細內容]
 

 

 設計模式的解析和實現之四-Prototype模式
作用:
  用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。
  UML結構圖:
點擊查看大圖
抽象基類:
1)Prototype:虛擬基類,所有原型的基類,提供Clone接口函數。
接口函數:
1)Prototype::Clone函數:純虛函數,根據不同的派生類來實例化創建對象。 [詳細內容]
 

 

 設計模式的解析和實現之五-Singleton模式
作用:
  保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
  UML結構圖:
點擊查看大圖
解析:
  Singleton模式其實是對全局靜態變量的一個取代策略,上面提到的Singleton模式的兩個作用在C++中是通過如下的機制實現的:1)僅有一個實例,提供一個類的靜態成員變量,大家知道類的靜態成員變量對於一個類的所有對象而言是惟一的 2)提供一個訪問它的全局訪問點,也就是提供對應的訪問這個靜態成員變量的靜態成員函數,對類的所有對象而言也是惟一的。在C++中,可以直接使用類域進行訪問而不必初始化一個類的對象。 [詳細內容]
 

 

 設計模式的解析和實現之六-Adapt模式
作用:
   將一個類的接口轉換成客戶希望的另外一個接口。Adapt 模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。
  UML結構圖
  1)采用繼承原有接口類的方式
點擊查看大圖
  2)采用組合原有接口類的方式
點擊查看大圖
解析:
Adapt模式其實就是把完成同樣的一個功能但是接口不能兼容的類橋接在一起使之可以在一起工作,這個模式使得復用舊的接口成為可能。 [詳細內容]
 

 

 設計模式的解析和實現之七-Bridge模式
作用:
  將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
  UML結構圖:
點擊查看大圖
抽象基類:
1)Abstraction:某個抽象類,它的實現方式由Implementor完成。
2)Implementor:實現類的抽象基類,定義了實現Abastraction的基本操作,而它的派生類實現這些接口。 [詳細內容]
 

 

 設計模式解析和實現之八-Composite模式
作用:
  將對象組合成樹形結構以表示“部分-整體”的層次結構。Composite使得用戶對單個對象和組合對象的使用具有一致性。
  UML結構圖:
點擊查看大圖
抽象基類:
1)Component:為組合中的對象聲明接口,聲明了類共有接口的缺省行為(如這里的Add,Remove,GetChild函數),聲明一個接口函數可以訪問Component的子組件。 [詳細內容]
 

 

 設計模式的解析和實現之九-Decorator模式
作用:
  動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator 模式相比生成子類更為靈活。
  UML結構圖:
點擊查看大圖
抽象基類:
1)Component:定義一個對象接口,可以為這個接口動態的添加職責。
2)Decorator:維持一個指向Component的指針,並且有一個和Component一致的接口函數。 [詳細內容]
 

 

 設計模式的解析和實現之十-Proxy模式
作用:
  為其他對象提供一種代理以控制對這個對象的訪問。
  UML結構圖:
點擊查看大圖
抽象基類:
1)Subject:定義了Proxy和RealSubject的公有接口,這樣就可以在任何需要使用到RealSubject的地方都使用Proxy.
解析:
   Proxy其實是基於這樣一種時常使用到的技術-某個對象直到它真正被使用到的時候才被初始化,在沒有使用到的時候就暫時用Proxy作一個占位符。這個模式實現的要點就是Proxy和RealSubject都繼承自Subject,這樣保證了兩個的接口都是一致的。 [詳細內容]
 

 

 設計模式的解析和實現之十一-TemplateMethod模式
作用:
  定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod 使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
  UML結構圖:
點擊查看大圖
抽象基類:
1)AbstractClass:抽象基類,定義算法的輪廓
解析:
TemplateMethod 的關鍵在於在基類中定義了一個算法的輪廓,但是算法每一步具體的實現留給了派生類。但是這樣也會造成設計的靈活性不高的缺點,因為輪廓已經定下來了要想改變就比較難了,這也是為什么優先采用聚合而不是繼承的原因。 [詳細內容]
 

 

 設計模式的解析和實現之十二-ChainOfResponsibility模式
作用:
  使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它為止。
  UML結構圖:
點擊查看大圖
抽象基類:
1)Handler:定義一個處理請求的接口,在圖中這個接口就是HandleRequset函數,這個類同時有一個指向Handler對象的指針,指向后續的處理請求的對象(如果有的話)。 [詳細內容]
 

 

 設計模式的解析和實現之十三-FlyWeight模式
作用:
  運用共享技術有效地支持大量細粒度的對象。
  UML結構圖:
點擊查看大圖
解析:
  Flyweight模式在大量使用一些可以被共享的對象的時候經常使用。比如,在QQ聊天的時候很多時候你懶得回復又不得不回復的時候,一般會用一些客套的話語敷衍別人,如"呵呵","好的"等等之類的,這些簡單的答復其實每個人都是提前定義好的,在使用的時候才調用出來。Flyweight就是基於解決這種問題的思路而產生的,當需要一個可以在其它地方共享使用的對象的時候,先去查詢是否已經存在了同樣的對象,如果沒有就生成之有的話就直接使用。因此,Flyweight模式和Factory模式也經常混用。 [詳細內容]
 

 

 設計模式的解析和實現之十四-Command模式
作用:
   將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以及支持可撤消的操作。
  UML結構圖:
點擊查看大圖
解析:
  Comnand模式的思想是把命令封裝在一個類中,就是這里的Command基類,同時把接收對象也封裝在一個類中就是這里的Receiver類中,由調用這個命令的類也就是這里的Invoker類來調用。其實,如果弄清楚了Command模式的原理,就會發現其實它和注冊回調函數的原理是很相似的,而在面向過程的設計中的回調函數其實和這里的Command類的作用是一致的。采用Command模式解耦了命令的發出者和命令的執行者。 [詳細內容]
 

 

 設計模式的解析和實現之十五-Observer模式
作用:
  定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。
  UML結構圖:
點擊查看大圖
抽象基類:
  Observer模式定義的是一種一對多的關系,這里的一就是圖中的Subject類,而多則是Obesrver類,當Subject類的狀態發生變化的時候通知與之對應的Obesrver類們也去相應的更新狀態,同時支持動態的添加和刪除Observer對象的功能。Obesrver模式的實現要點是... [詳細內容]
 

 

 設計模式的解析和實現之十六-Strategy模式
作用:
  定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得算法可獨立於使用它的客戶而變化。
解析:
  簡而言之一句話,Strategy模式是對算法的封裝。處理一個問題的時候可能有多種算法,這些算法的接口(輸入參數,輸出參數等)都是一致的,那么可以考慮采用Strategy模式對這些算法進行封裝,在基類中定義一個函數接口就可以了。[詳細內容]
 

 

  設計模式的解析和實現之十七-State模式
作用:
  允許一個對象在其內部狀態改變時改變它的行為。
  UML結構圖:
點擊查看大圖
解析:
   State模式主要解決的是在開發中時常遇到的根據不同的狀態需要進行不同的處理操作的問題,而這樣的問題,大部分人是采用switch-case語句進行處理的,這樣會造成一個問題:分支過多,而且如果加入一個新的狀態就需要對原來的代碼進行編譯。State模式采用... [詳細內容]
 

 

 設計模式的解析和實現之十八-Iterator模式
作用:
  提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。
  UML結構圖:
點擊查看大圖
解析:
  Iterator幾乎是大部分人在初學C++的時候就無意之中接觸到的第一種設計模式,因為在STL之中,所有的容器類都有與之相關的迭代器。以前初學STL的時候,時常在看到講述迭代器作用的時候是這么說的:提供一種方式,使得算法和容器可以獨立的變化,而且在訪問容器對象的時候... [詳細內容]
 

 

 設計模式的解析和實現之十九-Memento模式
作用:
  在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以后就可將該對象恢復到原先保存的狀態。
  UML結構圖:
點擊查看大圖
解析:
  Memento模式中封裝的是需要保存的狀態,當需要恢復的時候才取出來進行恢復。原理很簡單,實現的時候需要注意一個地方:窄接口和寬接口。所謂的寬接口就是一般意義上的接口,把對外的接口作為public成員;而窄接口反之,把接口作為private成員,而把需要訪問這些接口函數的類作為這個類的友元類,也就是說接口只暴露給了對這些接口感興趣的類,而不是暴露在外部。 [詳細內容]
 

 

 設計模式的解析和實現之二十-Visitor模式
作用:
  表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
  UML結構圖:
點擊查看大圖
解析:
  Visitor模式把對結點的訪問封裝成一個抽象基類,通過派生出不同的類生成新的訪問方式。在實現的時候,在visitor抽象基類中聲明了對所有不同結點進行訪問的接口函數,如圖中的VisitConcreateElementA函數等,這樣也造成了Visitor模式的一個缺陷——新加入一個結點的時候... [詳細內容]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM