1. 程式人生 > >【設計模式】全域性觀之為什麼分三大類

【設計模式】全域性觀之為什麼分三大類

引言

        距離設計模式敲完也有差不多一週多了,但是對於為什麼要分為三大類還是不太理解,於是就出來了這篇部落格

全域性觀

        大家都知道設計模式可以根據目的分為三大類,分別是建立型模式、結構型模式、行為型模式

        那麼為什麼這麼分呢?下面說一下筆者的理解

        建立型模式:主要用於處理物件的建立,例項化物件。但是,這可能會限制在系統內建立物件的型別或數目

        結構型模式:處理類或物件間的組合。它將以不同的方式影響著程式,允許在補充寫程式碼或自定義程式碼的情況下建立系統,而且具有重複使用性和應用效能

        行為型模式:描述類或物件怎樣進行互動和職責分配。影響系統的狀態、行為流,簡化、優化並且提高應用程式的可維護性


建立型模式

1、簡單工廠

當我們的程式在例項化物件時,如果輸入條件不一樣,產生的物件也不一樣,那麼我們可以考慮使用簡單工廠對不同的例項進行統一封裝

2、工廠方法

        它是針對簡單工廠的改進版,添加了對ProductManager的抽象

3、抽象工廠

        這個是最複雜的工廠模式,它用來生成一個產品線上的所有產品,我們假設一個產品線上包括多個產品,不同的產品線上的產品個數是一樣的,這樣我們需要一個針對產品線的抽象,並且很顯然不同產品線上的產品是不可能混到一起的

4、單例模式

        這是比較好理解的一個模式,從字面上說,就是程式在執行的過程中,希望在任意時刻,都只保留某個物件的唯一例項

5、建造者模式

        對於一些複雜物件來說,它可以分成多個不同的部分,在例項化時,不同部分之間例項化的順序,有時會有嚴格的限制,這時我們就可以使用建造者模式了

6、原型模式

        我們在程式執行過程中,當需要有新的例項物件時,有時並不希望是從頭建立一個物件,而是希望新的例項的狀態和某個已存在的例項保持一致,這就是原型模式發揮作用的地方

結構型模式

1、介面卡模式

        當我們已經開發出一個模組,有一套清晰的介面,並且模組正在被某個功能使用(意味著模組介面改變的可能性不高),這是如果有另外一個功能也需要使用這個模組的功能,但是對應的是一套完全不同的介面,這時介面卡就可以發揮作用了

2、裝飾模式

       假如我們已經開發了一套功能,然後根據需求,需要增加一些子功能,而且這些子功能是比較分散比較時可以增刪的,這時如果直接修改介面,那麼會造成介面功能複雜並且不穩定,針對這種情況,我們可以使用裝飾模式

3、橋接模式

        面向物件提倡的幾個最佳實踐包括:1)封裝變化;2)面向介面程式設計;3)組合優於繼承;4)類的職責儘量單一。橋接器完美的體現了這些,通過建立型模式,我們可以很好地達到面向介面程式設計的目標,也就是說我們在程式中各變數的宣告型別是介面型別或者抽象類,而具體的實現型別則由不同的設計模式使用不同方式指定

3、享元模式

        當我們系統中需要使用大量的小物件,但我們又不希望將所有的小物件都創建出來時,可以考慮使用享元模式,它會抽取小物件中的公共部分,將其封裝為基類,然後針對不同條件建立小物件,同時在物件池中維護這些小物件,客戶在需要使用小物件時,首先在物件池中查詢,如果存在,直接返回。對於小物件中“個性”的部分,由呼叫小物件的客戶端進行維護

4、組合模式

        當我們的物件結構中存在“父子”關係時,可以考慮使用組合模式

5、代理模式

        在編寫程式時,有時我們希望使用某個物件或者模組的功能,但是因為種種原因,我們不能直接訪問,這時就可以考慮使用代理模式

6、裝飾模式

        如果我們的程式需要深入呼叫某個模組的內部,但我們又不想和模組過緊耦合,這時可以考慮使用裝飾模式,來對外部封裝內部子系統的實現。簡單的裝飾可能和代理在某種程度上很相似。

行為型模式

1、職責鏈模式

        如果完成一項業務,需要很多步相關操作,但是如果將這些操作完全封裝到一個類或者方法裡面,又違背了單一職責的原則。這時我們可以考慮使用職責鏈模式

2、命令模式

        命令模式將發出命令和執行命令很好的區分開來,當我們執行某項業務時,客戶端只需要構造一個請求,而不必關心業務實現的具體細節,即構造請求和業務實現是獨立的

3、直譯器模式

        如果我們的系統中有些特定的問題反覆出現,我們想要對這些問題進行抽象,那應該如何做?試想一下,當我們寫完程式碼後,是如何進行編譯的?無論對C#還是Java,它們的編譯器都會讀取我們所寫的每一行程式碼,並作出相應的解釋。我們可以部分認為,編譯器中儲存了任何組合的語句,類似於C中的typedef。直譯器做的就是類似的事情,它將具有通用性的問題進行抽取,對其解決方案進行綜合處理

4、迭代器模式

        訪問者模式,針對的是儲存在一起的不同型別的物件集合,如何進行遍歷處理,那麼針對儲存在一起的相同型別的物件集合,我們應該如何進行遍歷呢?迭代器模式可以幫我們做到

5、中介者模式

        如果我們的系統中有多個物件,彼此之間都有聯絡,那這是一個物件之間耦合很高的系統,我們應該如何優化呢?我們可以建立一個知道所有物件的“物件”,在它內部維護其他物件之間的關聯,這就是中介者模式

6、備忘錄模式

        當我們的系統中存在這樣一種物件,它的屬性很多,在某些情況下,它的一部分屬性是需要進行備份和恢復的,那應該如何做?談到備份和恢復,我們立刻想到可以使用原型模式,但那是針對所有屬性的,備忘錄模式可以很好地解決這裡的問題

7、觀察者模式

         當我們的系統中,存在一個業務A,有其他多個業務都需要關注業務A,當它的狀態發生變化時,其他業務都需要做出相應操作,這時我們可以使用觀察者模式

8、狀態模式

        當我們的系統中的物件,需要根據傳入的不同引數,進行不同的處理,而且傳入引數的種類特別多,這時在方法內部會產生大量的if語句,來確定方法的執行分支。那麼如何消除這些if語句呢?狀態模式可以幫我們做到

9、策略模式

        當我們的系統中,針對某項業務有多個演算法時,如何對這些演算法進行管理,我們可以考慮使用策略模式,它主要是針對一組可以提取相同介面的演算法進行管理

10、模板方法模式

        繼承是面向物件的一大核心,而模板方法就是對繼承的完美體現。對於某項業務來說,我們可以根據通用的流程,設計其方法骨架,針對不清晰或者不明確的地方,以抽象方法的方式來處理,然後根據不同的子業務,建立不同的子類,在子類中,實現那些抽象方法

11、訪問者模式

        當我們有一個物件集合,集合中的元素型別是不一樣的,但型別是相對固定的,例如只有3種不同的型別,但是可能有30個元素。如果我們希望對集合中的所有元素進行某種操作,從介面的角度來看,由於型別不一致,我們很難通過一個統一的介面來遍歷集合元素並對其進行操作。這時我們可以考慮使用訪問者模式,它將獲取某個元素和對元素進行操作進行了分離

結語

        在學習一個東西之前,有一個全域性觀是很重要的,有助於你後面的學習。上文只是對設計模式有一個小小的介紹,具體詳細的敬請期待後面的部落格。關於設計模式,筆者只是個初學者,認識和理解比較淺顯,有待深究。

       本文只是對基礎知識做一個小小的總結,不深究。如有不同,見解歡迎指正

       本文所有內容均為作者原創,如有轉載,請註明出處