您好,登錄后才能下訂單哦!
創(chuàng)建型模式概述
創(chuàng)建型模式(Creational Pattern)對類的實例化過程進行了抽象,能夠將軟件模塊中對象的創(chuàng)建和對象的使用分離。為了使軟件的結構更加清晰,外界對于這些對象只需要知道它們共同的接口,而不清楚其具體的實現(xiàn)細節(jié),使整個系統(tǒng)的設計更加符合單一職責原則。
創(chuàng)建型模式概述
創(chuàng)建型模式在創(chuàng)建什么(What),由誰創(chuàng)建(Who),何時創(chuàng)建(When)等方面都為軟件設計者提供了盡可能大的靈活性。創(chuàng)建型模式隱藏了類的實例的創(chuàng)建細節(jié),通過隱藏對象如何被創(chuàng)建和組合在一起達到使整個系統(tǒng)獨立的目的。
一共包含6個模式
簡單工廠模式
工廠模式(Factory Method Pattern,多態(tài)工廠)
抽象工廠模式
單例模式
原型模式
建造者模式(Builder Pattern)
1簡單工廠模式
1.1優(yōu)點
(1) 工廠類包含必要的判斷邏輯,可以決定在什么時候創(chuàng)建哪一個產(chǎn)品類的實例,客戶端可以免除直接創(chuàng)建產(chǎn)品對象的職責,
而僅僅“消費”產(chǎn)品,簡單工廠模式實現(xiàn)了對象創(chuàng)建和使用的分離。
(2) 客戶端無須知道所創(chuàng)建的具體產(chǎn)品類的類名,只需要知道具體產(chǎn)品類所對應的參數(shù)即可,
對于一些復雜的類名,通過簡單工廠模式可以在一定程度減少使用者的記憶量。
(3) 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產(chǎn)品類,
在一定程度上提高了系統(tǒng)的靈活性。
1.2 缺點
(1) 由于工廠類集中了所有產(chǎn)品的創(chuàng)建邏輯,職責過重,一旦不能正常工作,整個系統(tǒng)都要受到影響。
(2) 使用簡單工廠模式勢必會增加系統(tǒng)中類的個數(shù)( 引入了新的工廠類) ,增加了系統(tǒng)的復雜度和理解難度。
(3) 系統(tǒng)擴展困難,一旦添加新產(chǎn)品就不得不修改工廠邏輯,在產(chǎn)品類型較多時,有可能造工廠邏輯過于復雜,不利于系統(tǒng)的擴展和維護。
(4) 簡單工廠模式由于使用了靜態(tài)工廠方法,造成工廠角色無法形成基于繼承的等級結構。
1.3 場景
工廠類負責創(chuàng)建的對象比較少:由于創(chuàng)建的對象較少,不會造成工廠方法中的業(yè)務邏輯太過復雜。
客戶端只知道傳入工廠類的參數(shù),對于如何創(chuàng)建對象不關心:客戶端既不需要關心創(chuàng)建細節(jié),甚至連類名都不需要記住,
只需要知道類型所對應的參數(shù)。
1.4 類圖
Factory:工廠角色
Product:抽象產(chǎn)品角色
ConcreteProduct:具體產(chǎn)品角色
2.工廠模式
具體工廠類負責創(chuàng)建
2.1優(yōu)點
在工廠方法模式中,工廠方法用來創(chuàng)建客戶所需要的產(chǎn)品,同時還向客戶隱藏了哪種具體產(chǎn)品類將被實例化這一細節(jié),用戶只需要關心所需產(chǎn)品對應的工廠,無須關心創(chuàng)建細節(jié),甚至無須知道具體產(chǎn)品類的類名。
基于工廠角色和產(chǎn)品角色的多態(tài)性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定創(chuàng)建何種產(chǎn)品對象,而如何創(chuàng)建這個對象的細節(jié)則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多態(tài)工廠模式,是因為所有的具體工廠類都具有同一抽象父類。
使用工廠方法模式的另一個優(yōu)點是在系統(tǒng)中加入新產(chǎn)品時,無須修改抽象工廠和抽象產(chǎn)品提供的接口,無須修改客戶端,也無須修改其他的具體工廠和具體產(chǎn)品,而只要添加一個具體工廠和具體產(chǎn)品就可以了。這樣,系統(tǒng)的可擴展性也就變得非常好,完全符合“開閉原則”。
2.2缺點
在添加新產(chǎn)品時,需要編寫新的具體產(chǎn)品類,而且還要提供與之對應的具體工廠類,系統(tǒng)中類的個數(shù)將成對增加,在一定程度上增加了系統(tǒng)的復雜度,有更多的類需要編譯和運行,會給系統(tǒng)帶來一些額外的開銷。
由于考慮到系統(tǒng)的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統(tǒng)的抽象性和理解難度,且在實現(xiàn)時可能需要用到DOM、反射等技術,增加了系統(tǒng)的實現(xiàn)難度。
2.3情景
一個類不知道它所需要的對象的類:在工廠方法模式中,客戶端不需要知道具體產(chǎn)品類的類名,只需要知道所對應的工廠即可,具體的產(chǎn)品對象由具體工廠類創(chuàng)建;客戶端需要知道創(chuàng)建具體產(chǎn)品的工廠類。
一個類通過其子類來指定創(chuàng)建哪個對象:在工廠方法模式中,對于抽象工廠類只需要提供一個創(chuàng)建產(chǎn)品的接口,而由其子類來確定具體要創(chuàng)建的對象,利用面向對象的多態(tài)性和里氏代換原則,在程序運行時,子類對象將覆蓋父類對象,從而使得系統(tǒng)更容易擴展。
將創(chuàng)建對象的任務委托給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類創(chuàng)建產(chǎn)品子類,需要時再動態(tài)指定,可將具體工廠類的類名存儲在配置文件或數(shù)據(jù)庫中。
2.4類圖
Product:抽象產(chǎn)品
ConcreteProduct:具體產(chǎn)品
Factory:抽象工廠
ConcreteFactory:具體工廠
3.抽象工廠模式
產(chǎn)品族
3.1優(yōu)點
抽象工廠模式隔離了具體類的生成,使得客戶并不需要知道什么被創(chuàng)建。由于這種隔離,更換一個具體工廠就變得相對容易。所有的具體工廠都實現(xiàn)了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例,就可以在某種程度上改變整個軟件系統(tǒng)的行為。另外,應用抽象工廠模式可以實現(xiàn)高內聚低耦合的設計目的,因此抽象工廠模式得到了廣泛的應用。
當一個產(chǎn)品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產(chǎn)品族中的對象。這對一些需要根據(jù)當前環(huán)境來決定其行為的軟件系統(tǒng)來說,是一種非常實用的設計模式。
增加新的具體工廠和產(chǎn)品族很方便,無須修改已有系統(tǒng),符合“開閉原則”。
3.2缺點
在添加新的產(chǎn)品對象時,難以擴展抽象工廠來生產(chǎn)新種類的產(chǎn)品,這是因為在抽象工廠角色中規(guī)定了所有可能被創(chuàng)建的產(chǎn)品集合,要支持新種類的產(chǎn)品就意味著要對該接口進行擴展,而這將涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。
開閉原則的傾斜性(增加新的工廠和產(chǎn)品族容易,增加新的產(chǎn)品等級結構麻煩)
3.3場景
一個系統(tǒng)不應當依賴于產(chǎn)品類實例如何被創(chuàng)建、組合和表達的細節(jié),這對于所有類型的工廠模式都是重要的。
系統(tǒng)中有多于一個的產(chǎn)品族,而每次只使用其中某一產(chǎn)品族。
屬于同一個產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設計中體現(xiàn)出來。
系統(tǒng)提供一個產(chǎn)品類的庫,所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶端不依賴于具體實現(xiàn)。
3.4類圖
AbstractFactory:抽象工廠
ConcreteFactory:具體工廠
AbstractProduct:抽象產(chǎn)品
Product:具體產(chǎn)品
4.單例模式
只有一個實例
4.1優(yōu)點
提供了對唯一實例的受控訪問。因為單例類封裝了它的唯一實例,所以它可以嚴格控制客戶怎樣以及何時訪問它,并為設計及開發(fā)團隊提供了共享的概念。
由于在系統(tǒng)內存中只存在一個對象,因此可以節(jié)約系統(tǒng)資源,對于一些需要頻繁創(chuàng)建和銷毀的對象,單例模式無疑可以提高系統(tǒng)的性能。
允許可變數(shù)目的實例。我們可以基于單例模式進行擴展,使用與單例控制相似的方法來獲得指定個數(shù)的對象實例。
4.2缺點
由于單例模式中沒有抽象層,因此單例類的擴展有很大的困難。
單例類的職責過重,在一定程度上違背了“單一職責原則”。因為單例類既充當了工廠角色,提供了工廠方法,同時又充當了產(chǎn)品角色,包含一些業(yè)務方法,將產(chǎn)品的創(chuàng)建和產(chǎn)品的本身的功能融合到一起。
濫用單例將帶來一些負面問題,如為了節(jié)省資源將數(shù)據(jù)庫連接池對象設計為單例類,可能會導致共享連接池對象的程序過多而出現(xiàn)連接池溢出;現(xiàn)在很多面向對象語言(如Java、C#)的運行環(huán)境都提供了自動垃圾回收的技術,因此,如果實例化的對象長時間不被利用,系統(tǒng)會認為它是垃圾,會自動銷毀并回收資源,下次利用時又將重新實例化,這將導致對象狀態(tài)的丟失。
4.3情景
系統(tǒng)只需要一個實例對象,如系統(tǒng)要求提供一個唯一的序列號生成器,或者需要考慮資源消耗太大而只允許創(chuàng)建一個對象。
客戶調用類的單個實例只允許使用一個公共訪問點,除了該公共訪問點,不能通過其他途徑訪問該實例。
在一個系統(tǒng)中要求一個類只有一個實例時才應當使用單例模式。反過來,如果一個類可以有幾個實例共存,就需要對單例模式進行改進,使之成為多例模式。
4.4類圖
Singleton:單例
5.原型模式
復制對象
5.1優(yōu)點
當創(chuàng)建新的對象實例較為復雜時,使用原型模式可以簡化對象的創(chuàng)建過程,通過一個已有實例可以提高新實例的創(chuàng)建效率。
可以動態(tài)增加或減少產(chǎn)品類。
原型模式提供了簡化的創(chuàng)建結構。
可以使用深克隆的方式保存對象的狀態(tài)。
5.2缺點
需要為每一個類配備一個克隆方法,而且這個克隆方法需要對類的功能進行通盤考慮,這對全新的類來說不是很難,但對已有的類進行改造時,不一定是件容易的事,必須修改其源代碼,違背了“開閉原則”。
在實現(xiàn)深克隆時需要編寫較為復雜的代碼。
5.3情景
創(chuàng)建新對象成本較大,新的對象可以通過原型模式對已有對象進行復制來獲得,如果是相似對象,則可以對其屬性稍作修改。
如果系統(tǒng)要保存對象的狀態(tài),而對象的狀態(tài)變化很小,或者對象本身占內存不大的時候,也可以使用原型模式配合備忘錄模式來應用。相反,如果對象的狀態(tài)變化很大,或者對象占用的內存很大,那么采用狀態(tài)模式會比原型模式更好。
需要避免使用分層次的工廠類來創(chuàng)建分層次的對象,并且類的實例對象只有一個或很少的幾個組合狀態(tài),通過復制原型對象得到新實例可能比使用構造函數(shù)創(chuàng)建一個新實例更加方便。
5.4類圖
Prototype:抽象原型類
ConcretePrototype:具體原型類
Client:客戶類
6.建造者模式
構建與表示分離
一步一步創(chuàng)建
6.1優(yōu)點
在建造者模式中,客戶端不必知道產(chǎn)品內部組成的細節(jié),將產(chǎn)品本身與產(chǎn)品的創(chuàng)建過程解耦,使得相同的創(chuàng)建過程可以創(chuàng)建不同的產(chǎn)品對象。
每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,用戶使用不同的具體建造者即可得到不同的產(chǎn)品對象。
可以更加精細地控制產(chǎn)品的創(chuàng)建過程。將復雜產(chǎn)品的創(chuàng)建步驟分解在不同的方法中,使得創(chuàng)建過程更加清晰,也更方便使用程序來控制創(chuàng)建過程。
增加新的具體建造者無須修改原有類庫的代碼,指揮者類針對抽象建造者類編程,系統(tǒng)擴展方便,符合“開閉原則”。
6.2缺點
建造者模式所創(chuàng)建的產(chǎn)品一般具有較多的共同點,其組成部分相似,如果產(chǎn)品之間的差異性很大,則不適合使用建造者模式,因此其使用范圍受到一定的限制。
如果產(chǎn)品的內部變化復雜,可能會導致需要定義很多具體建造者類來實現(xiàn)這種變化,導致系統(tǒng)變得很龐大。
6.3情景
需要生成的產(chǎn)品對象有復雜的內部結構,這些產(chǎn)品對象通常包含多個成員屬性。
需要生成的產(chǎn)品對象的屬性相互依賴,需要指定其生成順序。
對象的創(chuàng)建過程獨立于創(chuàng)建該對象的類。在建造者模式中引入了指揮者類,將創(chuàng)建過程封裝在指揮者類中,而不在建造者類中。
隔離復雜對象的創(chuàng)建和使用,并使得相同的創(chuàng)建過程可以創(chuàng)建不同的產(chǎn)品。
6.4類圖
Builder:抽象建造者
ConcreteBuilder:具體建造者
Director:指揮者
Product:產(chǎn)品角色
參照
https://www.gitbook.com/book/quanke/design-pattern-java/details
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。