1. 程式人生 > >軟件設計樣式學習

軟件設計樣式學習

函數 備忘錄 單例模式 維度 並且 命令模式 lba 匹配 面向對象編程

本文學習自 http://www.cnblogs.com/zhili/category/496417.html , 如有侵權,請聯系刪除。

1、單例模式

確保一個類只有一個實例,並提供一個全局訪問點

技術分享圖片

2、簡單工廠模式

簡單工廠直接依賴於工廠的產品,簡單工廠的處理函數包含了對產品的處理。

簡單工廠模式的缺點:

  • 工廠類集中了所有產品創建邏輯,一旦不能正常工作,整個系統都會受到影響。

  • 系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,這樣就會造成工廠邏輯過於復雜。

了解了簡單工廠模式之後的優缺點之後,我們之後就可以知道簡單工廠的應用場景了:

  • 當工廠類負責創建的對象比較少時可以考慮使用簡單工廠模式。

  • 客戶如果只知道傳入工廠類的參數,對於如何創建對象的邏輯不關心時可以考慮使用簡單工廠模式。

技術分享圖片

3、工廠模式

在工廠方法模式中,工廠類與具體產品類具有平行的等級結構,它們之間是一一對應的。

工廠方法模式通過面向對象編程中的多態性來將對象的創建延遲到具體工廠中,從而解決了簡單工廠模式中存在的問題,也很好地符合了開放封閉原則(即對擴展開放,對修改封閉)。

技術分享圖片

4、抽象工廠模式

抽象工廠模式:提供一個創建產品的接口來負責創建相關或依賴的對象,而不具體明確指定具體類

抽象工廠模式很難支持新種類產品的變化。這是因為抽象工廠接口中已經確定了可以被創建的產品集合,如果需要添加新產品,此時就必須去修改抽象工廠的接口,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發——封閉”原則。

知道了抽象工廠的優缺點之後,也就能很好地把握什麽情況下考慮使用抽象工廠模式了,下面就具體看看使用抽象工廠模式的系統應該符合那幾個前提:

一個系統不要求依賴產品類實例如何被創建、組合和表達的表達,這點也是所有工廠模式應用的前提。這個系統有多個系列產品,而系統中只消費其中某一系列產品系統要求提供一個產品類的庫,所有產品以同樣的接口出現,客戶端不需要依賴具體實現。

技術分享圖片

5、建造者模式

  1. 在建造者模式中,指揮者是直接與客戶端打交道的,指揮者將客戶端創建產品的請求劃分為對各個部件的建造請求,再將這些請求委派到具體建造者角色,具體建造者角色是完成具體產品的構建工作的,卻不為客戶所知道。

  2. 建造者模式主要用於“分步驟來構建一個復雜的對象”,其中“分步驟”是一個固定的組合過程,而復雜對象的各個部分是經常變化的。

  3. 產品不需要抽象類,由於建造模式的創建出來的最終產品可能差異很大,所以不大可能提煉出一個抽象產品類。

  4. 在前面文章中介紹的抽象工廠模式解決了“系列產品”的需求變化,而建造者模式解決的是 “產品部分” 的需要變化。

  5. 由於建造者隱藏了具體產品的組裝過程,所以要改變一個產品的內部表示,只需要再實現一個具體的建造者就可以了,從而能很好地應對產品組成組件的需求變化。

技術分享圖片

6、原型模式

原型模式用一個原型對象來指明所要創建的對象類型,然後用復制這個原型對象的方法來創建出更多的同類型對象,它與工廠方法模式的實現非常相似,其中原型模式中的Clone方法就類似工廠方法模式中的工廠方法,只是工廠方法模式的工廠方法是通過new運算符重新創建一個新的對象(相當於原型模式的深拷貝實現),而原型模式是通過調用MemberwiseClone方法來對原來對象進行拷貝,也就是復制,同時在原型模式優點中也介紹了與工廠方法的區別(第三點)。

技術分享圖片

7、適配器模式

適配器模式——把一個類的接口變換成客戶端所期待的另一種接口,從而使原本接口不匹配而無法一起工作的兩個類能夠在一起工作。

類的適配器模式:

優點:

  • 可以在不修改原有代碼的基礎上來復用現有類,很好地符合 “開閉原則”

  • 可以重新定義Adaptee(被適配的類)的部分行為,因為在類適配器模式中,Adapter是Adaptee的子類

  • 僅僅引入一個對象,並不需要額外的字段來引用Adaptee實例(這個即是優點也是缺點)。

缺點:

  • 用一個具體的Adapter類對Adaptee和Target進行匹配,當如果想要匹配一個類以及所有它的子類時,類的適配器模式就不能勝任了。因為類的適配器模式中沒有引入Adaptee的實例,光調用this.SpecificRequest方法並不能去調用它對應子類的SpecificRequest方法。

  • 采用了 “多繼承”的實現方式,帶來了不良的高耦合。

對象的適配器模式

優點:

  • 可以在不修改原有代碼的基礎上來復用現有類,很好地符合 “開閉原則”(這點是兩種實現方式都具有的)

  • 采用 “對象組合”的方式,更符合松耦合。

缺點:

  • 使得重定義Adaptee的行為較困難,這就需要生成Adaptee的子類並且使得Adapter引用這個子類而不是引用Adaptee本身。

適配器可以是抽象類,並適配器模式的實現是非常靈活的,我們完全可以將Adapter模式中的“現存對象”作為新的接口方法參數,適配器類可以根據參數參數可以返回一個合適的實例給客戶端。

技術分享圖片

8、橋接模式

橋接模式實現了抽象化與實現化的解耦,使它們相互獨立互不影響到對方。

優點:

把抽象接口與其實現解耦。

抽象和實現可以獨立擴展,不會影響到對方。

實現細節對客戶透明,對用於隱藏了具體實現細節。

缺點: 增加了系統的復雜度

橋接模式的使用場景,在以下情況下應當使用橋接模式:

  1. 如果一個系統需要在構件的抽象化角色和具體化角色之間添加更多的靈活性,避免在兩個層次之間建立靜態的聯系。

  2. 設計要求實現化角色的任何改變不應當影響客戶端,或者實現化角色的改變對客戶端是完全透明的。

  3. 需要跨越多個平臺的圖形和窗口系統上。

  4. 一個類存在兩個獨立變化的維度,且兩個維度都需要進行擴展。

技術分享圖片

9、裝飾者模式

裝飾者模式采用對象組合而非繼承的方式實現了再運行時動態地擴展對象功能的能力,而且可以根據需要擴展多個功能,避免了單獨使用繼承帶來的 ”靈活性差“和”多子類衍生問題“。同時它很好地符合面向對象設計原則中 ”優先使用對象組合而非繼承“和”開放-封閉“原則。

優點:裝飾這模式和繼承的目的都是擴展對象的功能,但裝飾者模式比繼承更靈活通過使用不同的具體裝飾類以及這些類的排列組合,設計師可以創造出很多不同行為的組合裝飾者模式有很好地可擴展性缺點:裝飾者模式會導致設計中出現許多小對象,如果過度使用,會讓程序變的更復雜。並且更多的對象會是的差錯變得困難,特別是這些對象看上去都很像。

技術分享圖片

10、組合模式

組合模式允許你將對象組合成樹形結構來表現”部分-整體“的層次結構,使得客戶以一致的方式處理單個對象以及對象的組合。

優點:

組合模式使得客戶端代碼可以一致地處理對象和對象容器,無需關系處理的單個對象,還是組合的對象容器。將”客戶代碼與復雜的對象容器結構“解耦。可以更容易地往組合對象中加入新的構件。缺點:使得設計更加復雜。客戶端需要花更多時間理清類之間的層次關系。(這個是幾乎所有設計模式所面臨的問題)。

註意的問題:

有時候系統需要遍歷一個樹枝結構的子構件很多次,這時候可以考慮把遍歷子構件的結構存儲在父構件裏面作為緩存。客戶端盡量不要直接調用樹葉類中的方法,而是借用其父類(Graphics)的多態性完成調用,這樣可以增加代碼的復用性。

技術分享圖片

11、外觀模式

外觀模式提供了一個統一的接口,用來訪問子系統中的一群接口。外觀定義了一個高層接口,讓子系統更容易使用。使用外觀模式時,我們創建了一個統一的類,用來包裝子系統中一個或多個復雜的類,客戶端可以直接通過外觀類來調用內部子系統中方法,從而外觀模式讓客戶和子系統之間避免了緊耦合。

使用了外觀模式之後,客戶端只依賴於外觀類,從而將客戶端與子系統的依賴解耦了,如果子系統發生改變,此時客戶端的代碼並不需要去改變。外觀模式的實現核心主要是——由外觀類去保存各個子系統的引用,實現由一個統一的外觀類去包裝多個子系統類,然而客戶端只需要引用這個外觀類,然後由外觀類來調用各個子系統中的方法。然而這樣的實現方式非常類似適配器模式,然而外觀模式與適配器模式不同的是:適配器模式是將一個對象包裝起來以改變其接口,而外觀是將一群對象 ”包裝“起來以簡化其接口。它們的意圖是不一樣的,適配器是將接口轉換為不同接口,而外觀模式是提供一個統一的接口來簡化接口。

優點:

  1. 外觀模式對客戶屏蔽了子系統組件,從而簡化了接口,減少了客戶處理的對象數目並使子系統的使用更加簡單。

  2. 外觀模式實現了子系統與客戶之間的松耦合關系,而子系統內部的功能組件是緊耦合的。松耦合使得子系統的組件變化不會影響到它的客戶。

缺點:

  1. 如果增加新的子系統可能需要修改外觀類或客戶端的源代碼,這樣就違背了”開——閉原則“(不過這點也是不可避免)。

技術分享圖片

12、享元模式

“既然都是同一個對象,能不能只創建一個對象,然後下次需要創建這個對象的時候,讓它直接用已經創建好了的對象就好了”,也就是說——讓一個對象共享。不錯,這個也是享元模式的實現精髓所在。

享元模式——運用共享技術有效地支持大量細粒度的對象。享元模式可以避免大量相似類的開銷,在軟件開發中如果需要生成大量細粒度的類實例來表示數據,如果這些實例除了幾個參數外基本上都是相同的,這時候就可以使用享元模式來大幅度減少需要實例化類的數量。如果能把這些參數(指的這些類實例不同的參數)移動類實例外面,在方法調用時將他們傳遞進來,這樣就可以通過共享大幅度地減少單個實例的數目。(這個也是享元模式的實現要領),然而我們把類實例外面的參數稱為享元對象的外部狀態,把在享元對象內部定義稱為內部狀態。具體享元對象的內部狀態與外部狀態的定義為:

內部狀態:在享元對象的內部並且不會隨著環境的改變而改變的共享部分

外部狀態:隨環境改變而改變的,不可以共享的狀態。

優點:

  1. 降低了系統中對象的數量,從而降低了系統中細粒度對象給內存帶來的壓力。

缺點:

  1. 為了使對象可以共享,需要將一些狀態外部化,這使得程序的邏輯更復雜,使系統復雜化。

  2. 享元模式將享元對象的狀態外部化,而讀取外部狀態使得運行時間稍微變長。

技術分享圖片

13、代理模式

代理模式——就是給某一個對象提供一個代理,並由代理對象控制對原對象的引用。在一些情況下,一個客戶不想或者不能直接引用一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。

優點:

  1. 代理模式能夠將調用用於真正被調用的對象隔離,在一定程度上降低了系統的耦合度;

  2. 代理對象在客戶端和目標對象之間起到一個中介的作用,這樣可以起到對目標對象的保護。代理對象可以在對目標對象發出請求之前進行一個額外的操作,例如權限檢查等。

缺點:

  1. 由於在客戶端和真實主題之間增加了一個代理對象,所以會造成請求的處理速度變慢

  2. 實現代理類也需要額外的工作,從而增加了系統的實現復雜度。

技術分享圖片

14、模板方法模式

模板方法模式——在一個抽象類中定義一個操作中的算法骨架(對應於生活中的大家下載的模板),而將一些步驟延遲到子類中去實現(對應於我們根據自己的情況向模板填充內容)。模板方法使得子類可以不改變一個算法的結構前提下,重新定義算法的某些特定步驟,模板方法模式把不變行為搬到超類中,從而去除了子類中的重復代碼。

把相同的部分抽象出來到抽象類中去定義,具體子類來實現具體的不同部分,這個思路也正式模板方法的實現精髓所在。

優點:

  1. 實現了代碼復用

  2. 能夠靈活應對子步驟的變化,符合開放-封閉原則

缺點:因為引入了一個抽象類,如果具體實現過多的話,需要用戶或開發人員需要花更多的時間去理清類之間的關系。

技術分享圖片

15、命令模式

命令模式屬於對象的行為型模式。命令模式是把一個操作或者行為抽象為一個對象中,通過對命令的抽象化來使得發出命令的責任和執行命令的責任分隔開。命令模式的實現可以提供命令的撤銷和恢復功能。

在下面的情況下可以考慮使用命令模式:

  1. 系統需要支持命令的撤銷(undo)。命令對象可以把狀態存儲起來,等到客戶端需要撤銷命令所產生的效果時,可以調用undo方法吧命令所產生的效果撤銷掉。命令對象還可以提供redo方法,以供客戶端在需要時,再重新實現命令效果。

  2. 系統需要在不同的時間指定請求、將請求排隊。一個命令對象和原先的請求發出者可以有不同的生命周期。意思為:原來請求的發出者可能已經不存在了,而命令對象本身可能仍是活動的。這時命令的接受者可以在本地,也可以在網絡的另一個地址。命令對象可以串行地傳送到接受者上去。

  3. 如果一個系統要將系統中所有的數據消息更新到日誌裏,以便在系統崩潰時,可以根據日誌裏讀回所有數據的更新命令,重新調用方法來一條一條地執行這些命令,從而恢復系統在崩潰前所做的數據更新。

  4. 系統需要使用命令模式作為“CallBack(回調)”在面向對象系統中的替代。Callback即是先將一個方法註冊上,然後再以後調用該方法。

命令模式使得命令發出的一個和接收的一方實現低耦合,從而有以下的優點:

  • 命令模式使得新的命令很容易被加入到系統裏。

  • 可以設計一個命令隊列來實現對請求的Undo和Redo操作。

  • 可以較容易地將命令寫入日誌。

  • 可以把命令對象聚合在一起,合成為合成命令。合成命令式合成模式的應用。

  命令模式的缺點:

  • 使用命令模式可能會導致系統有過多的具體命令類。這會使得命令模式在這樣的系統裏變得不實際。

技術分享圖片

16、叠代器模式

叠代器模式提供了一種方法順序訪問一個聚合對象(理解為集合對象)中各個元素,而又無需暴露該對象的內部表示,這樣既可以做到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據。

既然,叠代器模式承擔了遍歷集合對象的職責,則該模式自然存在2個類,一個是聚合類,一個是叠代器類。在面向對象涉及原則中還有一條是針對接口編程,所以,在叠代器模式中,抽象了2個接口,一個是聚合接口,另一個是叠代器接口,這樣叠代器模式中就四個角色了。

技術分享圖片

17、觀察者模式

從生活中的例子可以看出,只要對訂閱號進行關註的客戶端,如果訂閱號有什麽更新,就會直接推送給訂閱了的用戶。從中,我們就可以得出觀察者模式的定義。

  觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己的行為。

技術分享圖片

18、中介者模式

中介者模式,定義了一個中介對象來封裝系列對象之間的交互。中介者使各個對象不需要顯式地相互引用,從而使其耦合性降低,而且可以獨立地改變它們之間的交互。中介者模式一般應用於一組定義良好的對象之間需要進行通信的場合以及想定制一個分布在多個類中的行為,而又不想生成太多的子類的情形下。

中介者模式具有以下幾點優點:

  • 簡化了對象之間的關系,將系統的各個對象之間的相互關系進行封裝,將各個同事類解耦,使得系統變為松耦合。

  • 提供系統的靈活性,使得各個同事對象獨立而易於復用。

  然而,中介者模式也存在對應的缺點:

  • 中介者模式中,中介者角色承擔了較多的責任,所以一旦這個中介者對象出現了問題,整個系統將會受到重大的影響。例如,QQ遊戲中計算歡樂豆的程序出錯了,這樣會造成重大的影響。

  • 新增加一個同事類時,不得不去修改抽象中介者類和具體中介者類,此時可以使用觀察者模式和狀態模式來解決這個問題。

技術分享圖片

19、狀態者模式

每個對象都有其對應的狀態,而每個狀態又對應一些相應的行為,如果某個對象有多個狀態時,那麽就會對應很多的行為。那麽對這些狀態的判斷和根據狀態完成的行為,就會導致多重條件語句,並且如果添加一種新的狀態時,需要更改之前現有的代碼。這樣的設計顯然違背了開閉原則。狀態模式正是用來解決這樣的問題的。狀態模式將每種狀態對應的行為抽象出來成為單獨新的對象,這樣狀態的變化不再依賴於對象內部的行為。

狀態模式——允許一個對象在其內部狀態改變時自動改變其行為,對象看起來就像是改變了它的類。

在以下情況下可以考慮使用狀態者模式。

  • 當一個對象狀態轉換的條件表達式過於復雜時可以使用狀態者模式。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把復雜的判斷邏輯簡單化。

  • 當一個對象行為取決於它的狀態,並且它需要在運行時刻根據狀態改變它的行為時,就可以考慮使用狀態者模式。

狀態者模式的主要優點是:

  • 將狀態判斷邏輯每個狀態類裏面,可以簡化判斷的邏輯。

  • 當有新的狀態出現時,可以通過添加新的狀態類來進行擴展,擴展性好。

  狀態者模式的主要缺點是:

  • 如果狀態過多的話,會導致有非常多的狀態類,加大了開銷。

技術分享圖片

20、策略者模式

策略模式是針對一組算法,將每個算法封裝到具有公共接口的獨立的類中,從而使它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發生變化。

策略模式是對算法的包裝,是把使用算法的責任和算法本身分割開,委派給不同的對象負責。策略模式通常把一系列的算法包裝到一系列的策略類裏面。用一句話慨括策略模式就是——“將每個算法封裝到不同的策略類中,使得它們可以互換”。

在下面的情況下可以考慮使用策略模式:

  • 一個系統需要動態地在幾種算法中選擇一種的情況下。那麽這些算法可以包裝到一個個具體的算法類裏面,並為這些具體的算法類提供一個統一的接口。

  • 如果一個對象有很多的行為,如果不使用合適的模式,這些行為就只好使用多重的if-else語句來實現,此時,可以使用策略模式,把這些行為轉移到相應的具體策略類裏面,就可以避免使用難以維護的多重條件選擇語句,並體現面向對象涉及的概念。

策略模式主要是對方法的封裝,把一系列方法封裝到一系列的策略類中,從而使不同的策略類可以自由切換和避免在系統使用多重條件選擇語句來選擇針對不同情況來選擇不同的方法。

技術分享圖片

21、責任鏈模式

責任鏈模式指的是——某個請求需要多個對象進行處理,從而避免請求的發送者和接收之間的耦合關系。將這些對象連成一條鏈子,並沿著這條鏈子傳遞該請求,直到有對象處理它為止。

從責任鏈模式的定義可以發現,責任鏈模式涉及的對象只有處理者角色,但由於有多個處理者,它們具有共同的處理請求的方法,所以這裏抽象出一個抽象處理者角色進行代碼復用。

責任鏈模式的優點不言而喻,主要有以下點:

  • 降低了請求的發送者和接收者之間的耦合。

  • 把多個條件判定分散到各個處理類中,使得代碼更加清晰,責任更加明確。

  責任鏈模式也具有一定的缺點,如:

  • 在找到正確的處理對象之前,所有的條件判定都要執行一遍,當責任鏈過長時,可能會引起性能的問題

  • 可能導致某個請求不被處理。

技術分享圖片

22、訪問者模式

訪問者模式是封裝一些施加於某種數據結構之上的操作。一旦這些操作需要修改的話,接受這個操作的數據結構則可以保存不變。訪問者模式適用於數據結構相對穩定的系統, 它把數據結構和作用於數據結構之上的操作之間的耦合度降低,使得操作集合可以相對自由地改變。

  數據結構的每一個節點都可以接受一個訪問者的調用,此節點向訪問者對象傳入節點對象,而訪問者對象則反過來執行節點對象的操作。這樣的過程叫做“雙重分派”。節點調用訪問者,將它自己傳入,訪問者則將某算法針對此節點執行。

訪問者模式是用來封裝一些施加於某種數據結構之上的操作。它使得可以在不改變元素本身的前提下增加作用於這些元素的新操作,訪問者模式的目的是把操作從數據結構中分離出來。

技術分享圖片

23、備忘錄模式

備忘錄模式就是對某個類的狀態進行保存下來,等到需要恢復的時候,可以從備忘錄中進行恢復。生活中這樣的例子經常看到,如備忘電話通訊錄,備份操作操作系統,備份數據庫等。

  備忘錄模式的具體定義是:在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,這樣以後就可以把該對象恢復到原先的狀態。

備忘錄模式主要思想是——利用備忘錄對象來對保存發起人的內部狀態,當發起人需要恢復原來狀態時,再從備忘錄對象中進行獲取,在實際開發過程也應用到這點,例如數據庫中的事務處理。

備忘錄模式具有以下優點:

  • 如果某個操作錯誤地破壞了數據的完整性,此時可以使用備忘錄模式將數據恢復成原來正確的數據。

  • 備份的狀態數據保存在發起人角色之外,這樣發起人就不需要對各個備份的狀態進行管理。而是由備忘錄角色進行管理,而備忘錄角色又是由管理者角色管理,符合單一職責原則。

  當然,備忘錄模式也存在一定的缺點:

  • 在實際的系統中,可能需要維護多個備份,需要額外的資源,這樣對資源的消耗比較嚴重。

技術分享圖片

軟件設計樣式學習