設計模式總結(創建型、結構型)

来源:https://www.cnblogs.com/DiaoLintong/archive/2018/01/14/8282365.html
-Advertisement-
Play Games

前言 這篇博客主要介紹23種設計模式的適用範圍以及他們的優缺點,類圖儘量使用了實例的類圖來替代,沒有找到的類圖就用了設計模式本身的結構圖。 創建型模式 抽象工廠模式 提供一個創建產品的介面來負責創建相關或依賴的對象,而不具體明確指定具體類 優點: 抽象工廠模式將具體產品的創建延遲到具體工廠的子類中, ...


前言

這篇博客主要介紹23種設計模式的適用範圍以及他們的優缺點,類圖儘量使用了實例的類圖來替代,沒有找到的類圖就用了設計模式本身的結構圖。

創建型模式

抽象工廠模式

提供一個創建產品的介面來負責創建相關或依賴的對象,而不具體明確指定具體類

優點:

抽象工廠模式將具體產品的創建延遲到具體工廠的子類中,這樣將對象的創建封裝起來,可以減少客戶端與具體產品類之間的依賴,從而使系統耦合度低,這樣更有利於後期的維護和擴展。

缺點:

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

適用場景:

①一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節。

②系統中有多於一個的產品族,而每次只使用其中某一產品族。

③屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。

④產品等級結構穩定,設計完成之後,不會向系統中增加新的產品等級結構或者刪除已有的產品等級結構。

建造者模式

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。建造者模式的本質是使組裝過程(用指揮者類進行封裝,從而達到解耦的目的)和創建具體產品解耦,使我們不用去關心每個組件是如何組裝的。

建造者模式的實現:

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

②建造者模式主要用於“分步驟來構建一個複雜的對象”,其中“分步驟”是一個固定的組合過程,而複雜對象的各個部分是經常變化的(也就是說電腦的內部組件是經常變化的,這裡指的的變化如硬碟的大小變了,CPU由單核變雙核等)。

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

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

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

工廠方法模式

定義一個用於創建對象的介面,讓子類決定將哪一個類實例化。工廠方法模式讓一個類的實例化延遲到其子類。工廠方法模式又簡稱為工廠模式(Factory Pattern),又可稱作虛擬構造器模式(VirtualConstructor Pattern)或多態工廠模式(Polymorphic FactoryPattern)。

工廠方法模式之所以可以解決簡單工廠的模式,是因為它的實現把具體產品的創建推遲到子類中,此時工廠類不再負責所有產品的創建,而只是給出具體工廠必須實現的介面,這樣工廠方法模式就可以允許系統不修改工廠類邏輯的情況下來添加新產品,這樣也就剋服了簡單工廠模式中缺點。如果系統需要添加新產品時,我們可以利用多態性來完成系統的擴展,對於抽象工廠類和具體工廠中的代碼都不需要做任何改動。

原型模式

用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。

優點:

①原型模式向客戶隱藏了創建新實例的複雜性

②原型模式允許動態增加或較少產品類。

③原型模式簡化了實例的創建結構,工廠方法模式需要有一個與產品類等級結構相同的等級結構,而原型模式不需要這樣。

④產品類不需要事先確定產品的等級結構,因為原型模式適用於任何的等級結構

缺點:

①每個類必須配備一個克隆方法

②配備克隆方法需要對類的功能進行通盤考慮,這對於全新的類不是很難,但對於已有的類不一定很容易,特別當一個類引用不支持串列化的間接對象,或者引用含有迴圈結構的時候。

單例模式

確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例,這個類稱為單例類,它提供全局訪問的方法。

優點:

①單例模式具有一定的伸縮性,類自己來控制實例化進程,類就在改變實例化進程上有相應的伸縮性。

②由於在系統記憶體中只存在一個對象,因此可以節約系統資源,當需要頻繁創建和銷毀的對象時單例模式無疑可以提高系統的性能。

③避免對共用資源的多重占用。

缺點:

①不適用於變化的對象,如果同一類型的對象總是要在不同的用例場景發生變化,單例就會引起數據的錯誤,不能保存彼此的狀態。

②由於單利模式中沒有抽象層,因此單例類的擴展有很大的困難。

③單例類的職責過重,在一定程度上違背了“單一職責原則”。

適用場景:

單例模式只允許創建一個對象,因此節省記憶體,加快對象訪問速度,因此對象需要被公用的場合適合使用,如多個模塊使用同一個數據源連接對象等等。

結構型模式

適配器模式

將一個介面轉換成客戶希望的另一個介面,使介面不相容的那些類可以一起工作,其別名為包裝器(Wrapper)。適配器模式既可以作為類結構型模式,也可以作為對象結構型模式。

優點:

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

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

缺點:

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

適用場景:

①系統需要復用現有類,而該類的介面不符合系統的需求

②想要建立一個可重覆使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。

③對於對象適配器模式,在設計里需要改變多個已有子類的介面,如果使用類的適配器模式,就要針對每一個子類做一個適配器,而這不太實際。

橋接模式

將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種對象結構型模式,又稱為柄體(Handle and Body)模式或介面(Interface)模式。

優點:

①把抽象介面與其實現解耦。

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

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

缺點:

增加了系統的複雜度

使用場景:

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

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

③需要跨越多個平臺的圖形和視窗系統上。

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

組合模式

組合多個對象形成樹形結構以表示具有“整體—部分”關係的層次結構。組合模式對單個對象(即葉子對象)和組合對象(即容器對象)的使用具有一致性,組合模式又可以稱為“整體—部分”(Part-Whole)模式,它是一種對象結構型模式。

優點:

①組合模式使得客戶端代碼可以一致地處理對象和對象容器,無需關係處理的單個對象,還是組合的對象容器。

②將”客戶代碼與複雜的對象容器結構“解耦。

③可以更容易地往組合對象中加入新的構件。

缺點:

使得設計更加複雜。客戶端需要花更多時間理清類之間的層次關係。(這個是幾乎所有設計模式所面臨的問題)。

在以下情況下應該考慮使用組合模式:

①需要表示一個對象整體或部分的層次結構。

②希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。

裝飾模式

動態地給一個對象增加一些額外的職責,就增加對象功能來說,裝飾模式比生成子類實現更為靈活。裝飾模式是一種對象結構型模式。

優點:

①裝飾這模式和繼承的目的都是擴展對象的功能,但裝飾者模式比繼承更靈活

②通過使用不同的具體裝飾類以及這些類的排列組合,設計師可以創造出很多不同行為的組合

③裝飾者模式有很好地可擴展性

缺點:

①裝飾者模式會導致設計中出現許多小對象,如果過度使用,會讓程式變的更複雜。並且更多的對象會是的差錯變得困難,特別是這些對象看上去都很像。

使用場景:

①需要擴展一個類的功能或給一個類增加附加責任。

②需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。

③需要增加由一些基本功能的排列組合而產生的非常大量的功能

外觀模式

為子系統中的一組介面提供一個統一的入口。外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。

優點:

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

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

缺點:

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

使用場景:

①外一個複雜的子系統提供一個簡單的介面

②提供子系統的獨立性

③在層次化結構中,可以使用外觀模式定義系統中每一層的入口。其中三層架構就是這樣的一個例子。

享元模式

運用共用技術有效的支持大量細粒度的對象。

享元模式優點就在於它能夠大幅度的降低記憶體中對象的數量;而為了做到這一步也帶來了它的缺點:它使得系統邏輯複雜化,而且在一定程度上外蘊狀態影響了系統的速度。

使用場景:

①一個系統中有大量的對象,這些對象耗費大量的記憶體,這些對象中的狀態大部分都可以被外部化。

②這些對象可以按照內部狀態分成很多的組,當把外部對象從對象中剔除時,每一個組都可以僅用一個對象代替

③軟體系統不依賴這些對象的身份,

代理模式

給某一個對象提供一個代理或占位符,並由代理對象來控制對原對象的訪問。

優點:

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

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

缺點:

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

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

使用場景:

①遠程代理,也就是為一個對象在不同的地址空間提供局部代表。這樣可以隱藏一個對象存在於不同地址空間的事實。

②虛擬代理,是根據需要創建開銷很大的對象。通過它來存放實例化需要很長世間的真實對象。

③安全代理,用來控制真是對象訪問時的許可權。

④智能指引,是指當調用真實的對象時,代理處理另外一些事。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 事件分發機制是Android中非常重要的一個知識點,同時也是難點,相信到目前為止很多Android開發者對事件分發機制並沒有一個非常系統的認識,當然也包括博主個人在內。可能在平時的開發工作中我們並沒有意識到事件分發機制起到的作用,其實它是時刻存在的只是我們不知道而已,就像一些滑動衝突、點擊事件之間的 ...
  • 前言 前面幾篇說了執行環境相關的概念,本篇在次回顧下 執行環境(Execution context,簡稱EC,也稱執行上下文 ) 定義了變數或者函數有權訪問的數據,決定了各自行為,每個執行環境都有一個變數對象,之前我說執行環境可以先理解為 js代碼執行時所在的環境,其實把上下文當做是一個對象應該差不 ...
  • 14、函數 概念:定義一次,允許執行或調用多次 作用:允許重覆執行某段指定的語句塊 ü 函數的定義: (1)函數聲明式 - 就是函數定義的語法要求 | (2)字面量方式 - 類似於變數的定義方式 function 函數名( ){ | var 函數名 = function( ){ 函數體 | 函數體 ...
  • Q1 去掉一組整型數組重覆的值 比如輸入: [1,13,24,11,11,14,1,2] 輸出: [1,13,24,11,14,2] 需要去掉重覆的11 和 1 這兩個元素。 /** * unique an array **/ let unique = function(arr) { let has ...
  • 通過之前總結水平居中與垂直居中的基本方法,梳理垂直水平同時居中的方法就沒有那麼亂了。 text-align:center + line-height 如下圖,div2中用text-align+line-height實現單行文本水平垂直居中。 通過之前總結水平居中與垂直居中的基本方法,梳理垂直水平同時 ...
  • 昨天總結了css中水平居中的方法,今天來總結一下css中實現垂直居中的方法。 line-height line-height用於實現單行文本的垂直居中,如下圖中,我們要求單行文本垂直居中,只需要將div2設置行高line-height和height的值相同即可,也可以不用設置高度,因為單行文本的行高 ...
  • 其實呢,文件上傳的插件很多,可是現在做的東西要求儘量少用插件,所以就自己寫了一下。 之前也用node寫過對文件處理方面的東西,這次用php寫著試一下。 a.html文件 b.php文件: 在這當中也遇到了幾個問題 1.在PHP中通過print_r($_FILES)列印時,有時候formData裡面的 ...
  • 1 歷史起源 SGML——1986年國際標準化組織出版發佈了一個信息管理方面的國際標準(ISO 8879:1986信息處理)。 HTML 2.0——1995年11月作為RFC 1866發佈 XML 1.0——1998年,W3C發佈了XML1.0規範,使用它來簡化Internet的文檔信息傳輸 XHT ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...