做外貿(mào)網(wǎng)站詐騙株洲seo優(yōu)化哪家好
本系列文章簡介:
????????設(shè)計模式是在軟件開發(fā)過程中,經(jīng)過實踐和總結(jié)得到的一套解決特定問題的可復(fù)用的模板。它是一種在特定情境中經(jīng)過驗證的經(jīng)驗和技巧的集合,可以幫助開發(fā)人員設(shè)計出高效、可維護(hù)、可擴(kuò)展和可復(fù)用的軟件系統(tǒng)。設(shè)計模式提供了一種在設(shè)計和編碼過程中的指導(dǎo),它用于解決常見的設(shè)計問題,并提供了一種標(biāo)準(zhǔn)化的方案。設(shè)計模式能夠幫助開發(fā)人員降低系統(tǒng)的復(fù)雜性,提高代碼的可讀性和可維護(hù)性。本系列文章將詳細(xì)講解Java中的23中設(shè)計模式?,并配有圖文解析及相應(yīng)的代碼示例,歡迎大家訂閱《Java技術(shù)棧高級攻略》專欄,一起學(xué)習(xí),一起漲分!? ? ?
目錄
1、引言
2、設(shè)計模式概述
3、設(shè)計模式的基本要素
4、設(shè)計模式分類
4.1?創(chuàng)建型模式(Creational)
4.2?結(jié)構(gòu)型模式(Structural)
4.3?行為型模式(Behavioral)
5、設(shè)計模式概覽
6、設(shè)計模式詳解
6.1?創(chuàng)建型模式(Creational)
6.1.1 工廠模式(Factory Pattern)
6.1.1.1 簡介
?6.1.1.2? 優(yōu)缺點
?6.1.1.3??使用場景
?6.1.1.4??使用案例
6.1.2?抽象工廠模式(Abstract Factory Pattern)
6.1.2.1 簡介
6.1.2.2?優(yōu)缺點
6.1.2.3?使用場景
6.1.2.4?使用案例
6.1.3?單例模式(Singleton Pattern)
6.1.3.1 簡介
6.1.3.2?優(yōu)缺點
6.1.3.3?使用場景
6.1.3.4?使用案例
6.1.4?建造者模式(Builder Pattern)
6.1.4.1 簡介
6.1.4.2?優(yōu)缺點
6.1.4.3?使用場景
6.1.4.4?使用案例
6.1.5?原型模式(Prototype Pattern)
6.1.5.1 簡介
6.1.5.2?優(yōu)缺點
6.1.5.3?使用場景
6.1.5.4?使用案例
6.2?結(jié)構(gòu)型模式(Structural)
6.3?行為型模式(Behavioral)
7、結(jié)語
1、引言
????????設(shè)計模式是一種解決常見軟件設(shè)計問題的經(jīng)驗總結(jié),它提供了一套可重用的設(shè)計思想和方法,幫助開發(fā)人員更好地組織和設(shè)計他們的代碼。在軟件開發(fā)中,我們經(jīng)常會遇到一些常見的問題,比如如何實現(xiàn)代碼的靈活性、可擴(kuò)展性、可維護(hù)性和可復(fù)用性,以及如何減少代碼的耦合性等。設(shè)計模式通過定義一些通用的解決方案來解決這些問題,從而提高代碼的質(zhì)量和可維護(hù)性。
????????設(shè)計模式的概念最早由四位名為Gang of Four(GoF)的作者提出,他們在《設(shè)計模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書中總結(jié)了23種常見的設(shè)計模式。這些設(shè)計模式包括創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式,它們分別用于解決對象創(chuàng)建、對象組合和對象交互等問題。每個設(shè)計模式都有其固定的結(jié)構(gòu)和用法,開發(fā)人員可以根據(jù)具體的問題選擇合適的設(shè)計模式來解決。
????????本文將介紹這23種常見的設(shè)計模式,詳細(xì)解釋它們的原理、應(yīng)用場景和使用方法。通過學(xué)習(xí)這些設(shè)計模式,開發(fā)人員可以更好地理解軟件設(shè)計的原則和思想,提高自己的設(shè)計能力和編碼水平。設(shè)計模式不僅是一種編碼技巧,更是一種思維方式和設(shè)計原則的體現(xiàn)。希望通過本文的介紹,讀者能夠更好地掌握和應(yīng)用設(shè)計模式,寫出更優(yōu)雅、可擴(kuò)展和可維護(hù)的代碼。
2、設(shè)計模式概述
????????設(shè)計模式是一種解決問題的可復(fù)用的設(shè)計思路,它提供了一套經(jīng)驗豐富且經(jīng)過驗證的解決方案。設(shè)計模式可以幫助開發(fā)人員在軟件開發(fā)過程中更加靈活、高效地解決常見問題,并提高代碼的可維護(hù)性和可擴(kuò)展性。設(shè)計模式提供了一種標(biāo)準(zhǔn)化和結(jié)構(gòu)化的方法來解決一些常見的設(shè)計問題,使得代碼更易于理解和維護(hù)。
3、設(shè)計模式的基本要素
設(shè)計模式的基本要素包括:
-
模式名稱:設(shè)計模式通常以一個或多個詞來描述模式的目的和特征。
-
問題描述:模式描述了一個常見的問題或場景,涉及到解決特定問題時的需求和約束條件。
-
解決方案:模式描述了一個通用的解決方案,用于解決特定問題或滿足特定需求。
-
結(jié)構(gòu):模式描述了解決方案的組成部分和它們之間的關(guān)系。
-
參與者:模式描述了解決方案中的角色和它們之間的通信和協(xié)作關(guān)系。
-
協(xié)作:模式描述了參與者之間如何協(xié)同工作來達(dá)到特定目的。
-
效果:模式描述了解決方案帶來的優(yōu)點和可能的缺點。
-
相關(guān)模式:模式描述了該模式與其他模式之間的關(guān)系和相互作用。
-
示例代碼:模式通常會提供一個或多個示例代碼,用于演示如何實現(xiàn)和使用該模式。
-
應(yīng)用場景:模式描述了適用該模式的問題或場景,并提供了一些使用該模式的示例場景。
這些要素共同描述了一個設(shè)計模式的目的、解決方案和應(yīng)用方式,幫助開發(fā)人員更好地理解和應(yīng)用設(shè)計模式。
4、設(shè)計模式分類
????????設(shè)計模式是解決軟件設(shè)計中常見問題的典型解決方案的規(guī)范化描述。根據(jù)問題和解決方案的不同,設(shè)計模式可以分為三大類:創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式。
4.1?創(chuàng)建型模式(Creational)
創(chuàng)建型模式是一種軟件設(shè)計模式,它提供了一種創(chuàng)建對象的機(jī)制,可以根據(jù)需要動態(tài)地創(chuàng)建對象,而無需直接實例化對象。
創(chuàng)建型模式包括以下幾種:
-
工廠模式(Factory Pattern):定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到子類。
-
抽象工廠模式(Abstract Factory Pattern):提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。
-
單例模式(Singleton Pattern):保證一個類只有一個實例,并提供一個全局訪問點。
-
建造者模式(Builder Pattern):將一個復(fù)雜對象的構(gòu)建過程與其表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
-
原型模式(Prototype Pattern):通過復(fù)制現(xiàn)有對象來創(chuàng)建新對象,而不是使用構(gòu)造函數(shù)。
這些模式的目的都是提供一種靈活的方式來創(chuàng)建對象,使得系統(tǒng)更加可擴(kuò)展和可維護(hù)。通過使用這些模式,可以將對象的創(chuàng)建過程和使用過程分離,降低耦合性,提高代碼的復(fù)用性和可測試性。
4.2?結(jié)構(gòu)型模式(Structural)
結(jié)構(gòu)型模式是設(shè)計模式的一種,用于解決對象之間的組合、關(guān)聯(lián)和結(jié)構(gòu)的問題。結(jié)構(gòu)型模式可以幫助我們設(shè)計和組織類、對象和系統(tǒng)的結(jié)構(gòu),以便于更好地實現(xiàn)系統(tǒng)的功能。
常見的結(jié)構(gòu)型模式包括以下幾種:
-
適配器模式(Adapter Pattern):用于將一個類的接口轉(zhuǎn)換成客戶端所期望的另一種接口。
-
橋接模式(Bridge Pattern):將抽象部分與實現(xiàn)部分分離,使它們可以獨立變化。
-
組合模式(Composite Pattern):將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。
-
裝飾器模式(Decorator Pattern):動態(tài)地給對象添加額外的職責(zé)。
-
外觀模式(Facade Pattern):提供一個統(tǒng)一的接口,用于訪問子系統(tǒng)中的一群接口。
-
享元模式(Flyweight Pattern):使用共享對象可有效地支持大量的細(xì)粒度的對象。
-
代理模式(Proxy Pattern):為其他對象提供一個代理以控制對這個對象的訪問。
這些結(jié)構(gòu)型模式可以根據(jù)不同的情況選擇使用,以解決特定的設(shè)計問題。
4.3?行為型模式(Behavioral)
行為型模式是軟件設(shè)計中的一種設(shè)計模式,用于描述對象之間的相互作用和通信方式。行為型模式關(guān)注的是對象的行為和責(zé)任的分配,以及對象之間的相互關(guān)系,實現(xiàn)對象之間的松耦合。
常見的行為型模式包括:
-
解釋器模式(Interpreter Pattern):給定一個語言,定義其文法的一種表示,并定義一個解釋器,用來解釋該語言中的句子。
-
模板方法模式(Template Method Pattern):一種行為型設(shè)計模式,它定義了一個算法的骨架,將一些步驟的具體實現(xiàn)延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義某些步驟的實現(xiàn)。
-
觀察者模式(Observer Pattern):定義了一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都會被通知并自動更新。
-
策略模式(Strategy Pattern):定義了一系列的算法,并將其封裝成獨立的對象,使得它們可以互相替換。策略模式使得算法可以獨立于客戶端而變化。
-
命令模式(Command Pattern):將請求封裝成對象,使得可以將請求的發(fā)送者和接收者解耦,實現(xiàn)請求的發(fā)送者和接收者之間的松耦合。
-
職責(zé)鏈模式(Chain of Responsibility Pattern):將請求的發(fā)送者和接收者解耦,使多個對象都有機(jī)會處理該請求,將這些對象串成一條鏈,并沿著這條鏈傳遞該請求,直到有對象處理它。
-
迭代器模式(Iterator Pattern):提供一種訪問一個容器對象中各個元素的方式,而不需要暴露該對象的內(nèi)部表示。
-
中介者模式(Mediator Pattern):用一個中介對象封裝一系列對象的交互,中介者使各個對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。
-
備忘錄模式(Memento Pattern):在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可以把該對象恢復(fù)到之前的狀態(tài)。
-
狀態(tài)模式(State Pattern):允許一個對象在其內(nèi)部狀態(tài)改變時改變其行為,對象看起來似乎修改了其類。
-
訪問者模式(Visitor Pattern):表示一個作用于某對象結(jié)構(gòu)中的各元素的操作,可以在不改變這些元素的類的前提下定義新的操作。
5、設(shè)計模式概覽
模型分類 | 范圍? ? ? | 模式名稱 | 模式描述 |
---|---|---|---|
創(chuàng)建型 | 類 | 工廠模式 (Factory Pattern) | 定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到子類。 |
對象 ? | 抽象工廠模式 (Abstract Factory Pattern) | 提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。 | |
單例模式 (Singleton Pattern) | 保證一個類只有一個實例,并提供一個全局訪問點。 | ||
建造者模式 (Builder Pattern) | 將一個復(fù)雜對象的構(gòu)建過程與其表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 | ||
原型模式 (Prototype Pattern) | 通過復(fù)制現(xiàn)有對象來創(chuàng)建新對象,而不是使用構(gòu)造函數(shù)。 | ||
結(jié)構(gòu)型 | 類 | 適配器模式 (Adapter Pattern) | 用于將一個類的接口轉(zhuǎn)換成客戶端所期望的另一種接口。 |
對象 | 橋接模式 (Bridge Pattern) | 將抽象部分與實現(xiàn)部分分離,使它們可以獨立變化。 | |
組合模式 (Composite Pattern) | 將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。 | ||
裝飾器模式 (Decorator Pattern) | 動態(tài)地給對象添加額外的職責(zé)。 | ||
外觀模式 (Facade Pattern) | 提供一個統(tǒng)一的接口,用于訪問子系統(tǒng)中的一群接口。 | ||
享元模式 (Flyweight Pattern) | 使用共享對象可有效地支持大量的細(xì)粒度的對象。 | ||
代理模式 (Proxy Pattern) | 為其他對象提供一個代理以控制對這個對象的訪問。 | ||
行為型 | 類 | 解釋器模式 (Interpreter Pattern) | 給定一個語言,定義其文法的一種表示,并定義一個解釋器,用來解釋該語言中的句子。 |
模板方法模式 (Template Method Pattern) | 一種行為型設(shè)計模式,它定義了一個算法的骨架,將一些步驟的具體實現(xiàn)延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義某些步驟的實現(xiàn)。 | ||
對象 | 觀察者模式 (Observer Pattern) | 定義了一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都會被通知并自動更新。 | |
策略模式 (Strategy Pattern) | 定義了一系列的算法,并將其封裝成獨立的對象,使得它們可以互相替換。策略模式使得算法可以獨立于客戶端而變化。 | ||
命令模式 (Command Pattern) | 將請求封裝成對象,使得可以將請求的發(fā)送者和接收者解耦,實現(xiàn)請求的發(fā)送者和接收者之間的松耦合。 | ||
職責(zé)鏈模式 (Chain of Responsibility Pattern) | 將請求的發(fā)送者和接收者解耦,使多個對象都有機(jī)會處理該請求,將這些對象串成一條鏈,并沿著這條鏈傳遞該請求,直到有對象處理它。 | ||
迭代器模式 (Iterator Pattern) | 提供一種訪問一個容器對象中各個元素的方式,而不需要暴露該對象的內(nèi)部表示。 | ||
中介者模式 (Mediator Pattern) | 用一個中介對象封裝一系列對象的交互,中介者使各個對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。 | ||
備忘錄模式 (Memento Pattern) | 在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可以把該對象恢復(fù)到之前的狀態(tài)。 | ||
狀態(tài)模式 (State Pattern) | 允許一個對象在其內(nèi)部狀態(tài)改變時改變其行為,對象看起來似乎修改了其類。 | ||
訪問者模式 (Visitor Pattern) | 表示一個作用于某對象結(jié)構(gòu)中的各元素的操作,可以在不改變這些元素的類的前提下定義新的操作。 |
6、設(shè)計模式詳解
6.1?創(chuàng)建型模式(Creational)
6.1.1 工廠模式(Factory Pattern)
6.1.1.1 簡介
????????工廠模式是一種創(chuàng)建對象的設(shè)計模式,它通過定義一個工廠類來創(chuàng)建對象實例,而不是通過直接調(diào)用構(gòu)造函數(shù)來創(chuàng)建對象。工廠模式將對象的創(chuàng)建過程封裝在工廠類中,客戶端只需要通過工廠類來創(chuàng)建對象,而不需要了解對象的具體實現(xiàn)細(xì)節(jié)。
????????工廠模式可以將對象的創(chuàng)建與使用分離,提供了一種靈活的方式來創(chuàng)建對象。它可以根據(jù)實際的需求來選擇具體的對象實現(xiàn),并且可以隨時更換對象的實現(xiàn),而不影響客戶端的代碼。
????????在工廠模式中,通常有一個抽象工廠類,該類定義了創(chuàng)建對象的接口,具體的對象創(chuàng)建由具體的工廠子類來實現(xiàn)。客戶端通過調(diào)用工廠類的方法來創(chuàng)建對象,而不需要直接調(diào)用構(gòu)造函數(shù)。這樣可以將對象的創(chuàng)建過程集中在工廠類中,方便管理和維護(hù)。
????????工廠模式可以根據(jù)具體的需求來創(chuàng)建不同類型的對象,例如創(chuàng)建數(shù)據(jù)庫連接、創(chuàng)建窗口控件、創(chuàng)建日志對象等。它能夠提供一種統(tǒng)一的接口來創(chuàng)建對象,方便擴(kuò)展和修改對象的實現(xiàn),同時也提高了代碼的可維護(hù)性和可讀性。
?6.1.1.2? 優(yōu)缺點
工廠模式的優(yōu)點:
- 降低代碼耦合度:工廠模式將對象的創(chuàng)建和使用分離,客戶端只需要知道工廠接口,而不需要知道具體的產(chǎn)品實現(xiàn)類,降低了代碼的耦合度。
- 簡化對象創(chuàng)建過程:通過工廠模式,可以隱藏對象創(chuàng)建的細(xì)節(jié),客戶端只需要調(diào)用工廠方法即可獲得所需的對象,簡化了對象創(chuàng)建過程。
- 擴(kuò)展性好:當(dāng)需要新增一種產(chǎn)品時,只需要新增對應(yīng)的產(chǎn)品實現(xiàn)類和工廠類,不需要修改已有代碼,符合開閉原則。
- 提供接口的統(tǒng)一管理:工廠模式通過工廠接口來管理具體產(chǎn)品的創(chuàng)建,可以統(tǒng)一管理和控制產(chǎn)品的生成過程。
工廠模式的缺點:
- 增加了系統(tǒng)的抽象性和理解難度:工廠模式引入了額外的抽象層,增加了系統(tǒng)的復(fù)雜性和理解難度,不適用于簡單的場景。
- 增加了系統(tǒng)的類的個數(shù):引入工廠模式會增加系統(tǒng)的類的數(shù)量,增加了代碼量和維護(hù)成本。
- 不符合開閉原則:工廠模式在新增產(chǎn)品時,需要新增相應(yīng)的產(chǎn)品實現(xiàn)類和工廠類,違背了開閉原則。
?6.1.1.3??使用場景
工廠模式適用于以下場景:
- 當(dāng)一個類無法預(yù)知需要創(chuàng)建哪種類型的對象時,可以使用工廠模式。工廠類會根據(jù)傳入的參數(shù)或條件來決定創(chuàng)建哪種類型的對象。
- 當(dāng)創(chuàng)建一個對象的過程比較復(fù)雜,需要進(jìn)行一些初始化操作或者涉及到多個步驟時,可以使用工廠模式。工廠類可以對這些復(fù)雜的創(chuàng)建過程進(jìn)行封裝,使調(diào)用方只需要簡單地調(diào)用工廠方法即可得到所需的對象。
- 當(dāng)需要統(tǒng)一管理創(chuàng)建的對象時,可以使用工廠模式。工廠類可以負(fù)責(zé)對象的創(chuàng)建、緩存、銷毀等管理操作,使對象的生命周期得到有效的控制。
- 當(dāng)需要將對象的創(chuàng)建與使用解耦時,可以使用工廠模式。調(diào)用方只需要通過工廠類來獲取所需的對象,而不需要關(guān)心對象的具體創(chuàng)建細(xì)節(jié)。
- 當(dāng)需要通過某種方式動態(tài)地切換對象的創(chuàng)建方式時,可以使用工廠模式。只需要修改工廠類的實現(xiàn),而不需要修改調(diào)用方的代碼,就可以實現(xiàn)對象創(chuàng)建方式的切換。
?6.1.1.4??使用案例
工廠模式是一種常用的設(shè)計模式,用于創(chuàng)建對象的實例化過程封裝。它提供了一種通過調(diào)用工廠方法來創(chuàng)建對象的方式,而無需直接使用new關(guān)鍵字來實例化對象。
下面是一個簡單的工廠模式的Java使用案例:
首先,我們定義一個接口Shape
,用于表示各種形狀:
public interface Shape {void draw();
}
然后,我們實現(xiàn)三個具體的形狀類,分別是Circle
、Rectangle
和Square
,它們都實現(xiàn)了Shape
接口:
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a circle");}
}public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a rectangle");}
}public class Square implements Shape {@Overridepublic void draw() {System.out.println("Drawing a square");}
}
接下來,我們創(chuàng)建一個工廠類ShapeFactory
,用于根據(jù)給定的參數(shù)創(chuàng)建不同的形狀對象:
public class ShapeFactory {public Shape createShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("circle")) {return new Circle();} else if (shapeType.equalsIgnoreCase("rectangle")) {return new Rectangle();} else if (shapeType.equalsIgnoreCase("square")) {return new Square();}return null;}
}
最后,我們可以在客戶端代碼中使用工廠類來創(chuàng)建并使用不同形狀的對象:
public class Main {public static void main(String[] args) {ShapeFactory factory = new ShapeFactory();// 創(chuàng)建一個圓形Shape circle = factory.createShape("circle");circle.draw();// 創(chuàng)建一個矩形Shape rectangle = factory.createShape("rectangle");rectangle.draw();// 創(chuàng)建一個正方形Shape square = factory.createShape("square");square.draw();}
}
運(yùn)行上述代碼,輸出結(jié)果如下:
Drawing a circle
Drawing a rectangle
Drawing a square
通過工廠模式,我們可以將對象的創(chuàng)建過程封裝起來,使客戶端代碼與具體對象的類耦合度降低,增強(qiáng)了代碼的可擴(kuò)展性和可維護(hù)性。
6.1.2?抽象工廠模式(Abstract Factory Pattern)
6.1.2.1 簡介
????????抽象工廠模式是一種設(shè)計模式,旨在提供一個統(tǒng)一的接口來創(chuàng)建一系列相關(guān)或相互依賴的對象,而無需指定具體的類。
????????在抽象工廠模式中,有一個抽象工廠類,聲明了創(chuàng)建不同類型對象的抽象方法。具體的工廠類繼承自抽象工廠類,并實現(xiàn)了抽象方法來創(chuàng)建具體的對象。每個具體的工廠類對應(yīng)一組具體的產(chǎn)品類。
????????在客戶端代碼中,通過實例化具體的工廠類,可以得到一組具體的產(chǎn)品對象??蛻舳舜a與具體的工廠類及產(chǎn)品類分離,可以方便地替換不同工廠類或產(chǎn)品類。
????????抽象工廠模式可以幫助我們實現(xiàn)高層的解耦,同時還可以提供一定程度的擴(kuò)展性。缺點是如果有新的產(chǎn)品類需要添加,需要修改抽象工廠類的接口及所有的具體工廠類。
6.1.2.2?優(yōu)缺點
抽象工廠模式是一種用于創(chuàng)建相關(guān)或依賴對象系列的設(shè)計模式。它提供了一種將具體類的實例化延遲到子類的方法,以便子類可以決定創(chuàng)建的具體對象類型。
優(yōu)點:
- 隔離了具體類的實現(xiàn):客戶端只需要知道抽象工廠和抽象產(chǎn)品的接口,而不需要了解具體的實現(xiàn)。這樣可以減少客戶端與具體類的耦合,使得系統(tǒng)更加靈活和可擴(kuò)展。
- 提供了一種可替換的實現(xiàn):由于抽象工廠模式將具體類的實現(xiàn)與客戶端分離,可以很容易地替換具體工廠和產(chǎn)品的實現(xiàn),從而實現(xiàn)系統(tǒng)的靈活性。
- 符合開閉原則:當(dāng)需要新增一種產(chǎn)品系列時,只需要新增對應(yīng)的具體工廠和產(chǎn)品類,不需要修改已有的代碼,符合開閉原則。
缺點:
- 增加了系統(tǒng)的復(fù)雜性:引入抽象工廠模式會增加系統(tǒng)的類和對象數(shù)量,增加了系統(tǒng)的復(fù)雜性,使得系統(tǒng)難以理解和維護(hù)。
- 不易擴(kuò)展新的產(chǎn)品:由于抽象工廠模式中的抽象工廠和產(chǎn)品是固定的,當(dāng)需要新增一種產(chǎn)品時,需要修改抽象工廠和所有具體工廠的代碼,導(dǎo)致系統(tǒng)擴(kuò)展困難。
- 不符合單一職責(zé)原則:抽象工廠模式將一系列產(chǎn)品的創(chuàng)建邏輯封裝在一個工廠類中,可能會導(dǎo)致該工廠類承擔(dān)過多的職責(zé),違反了單一職責(zé)原則。
6.1.2.3?使用場景
抽象工廠模式通常在以下場景中使用:
-
當(dāng)需要創(chuàng)建一組相互關(guān)聯(lián)或相互依賴的對象時,可以使用抽象工廠模式。例如,在一個圖形編輯器中,需要創(chuàng)建不同類型的圖形對象(如圓形、正方形、矩形等),并且這些對象需要具有相同的樣式(如顏色、邊框樣式等),可以使用抽象工廠模式創(chuàng)建不同類型的圖形對象和樣式對象。
-
當(dāng)需要創(chuàng)建一組具有相同接口的對象,并且客戶端不關(guān)心具體實現(xiàn)時,可以使用抽象工廠模式。例如,在一個圖形界面庫中,需要提供不同類型的按鈕和文本框,但是客戶端只需要關(guān)心這些組件具備的基本功能(如點擊事件、輸入文本等),可以使用抽象工廠模式創(chuàng)建不同類型的按鈕和文本框?qū)ο蟆?/p>
-
當(dāng)希望客戶端與具體類的實現(xiàn)解耦時,可以使用抽象工廠模式。例如,客戶端需要使用數(shù)據(jù)庫訪問接口進(jìn)行數(shù)據(jù)操作,但是不希望直接依賴于某個具體的數(shù)據(jù)庫實現(xiàn),可以使用抽象工廠模式創(chuàng)建數(shù)據(jù)庫訪問接口的具體實現(xiàn)。
-
當(dāng)需要在運(yùn)行時動態(tài)切換不同的產(chǎn)品族時,可以使用抽象工廠模式。例如,在一個電子設(shè)備管理系統(tǒng)中,需要支持不同供應(yīng)商的設(shè)備(如攝像頭、打印機(jī)等),可以使用抽象工廠模式創(chuàng)建不同供應(yīng)商的設(shè)備對象,并在運(yùn)行時動態(tài)切換不同的設(shè)備供應(yīng)商。
總之,抽象工廠模式適用于需要創(chuàng)建一組相關(guān)對象,并且希望客戶端與具體實現(xiàn)解耦的場景。
6.1.2.4?使用案例
下面是一個使用抽象工廠模式的Java案例,假設(shè)我們正在開發(fā)一個角色扮演游戲,需要創(chuàng)建不同種類的角色和武器。
首先,我們需要定義一個抽象工廠接口CharacterFactory
,該接口包含了創(chuàng)建角色和武器的方法:
public interface CharacterFactory {Character createCharacter();Weapon createWeapon();
}
然后,我們實現(xiàn)了兩個具體的工廠類MedievalFactory
和SciFiFactory
,分別用于創(chuàng)建中世紀(jì)和科幻風(fēng)格的角色和武器:
// 中世紀(jì)工廠
public class MedievalFactory implements CharacterFactory {public Character createCharacter() {return new Knight();}public Weapon createWeapon() {return new Sword();}
}// 科幻工廠
public class SciFiFactory implements CharacterFactory {public Character createCharacter() {return new Robot();}public Weapon createWeapon() {return new LaserGun();}
}
接下來,我們定義了兩個角色類Knight
和Robot
,以及兩種武器類Sword
和LaserGun
,分別對應(yīng)中世紀(jì)和科幻風(fēng)格的角色和武器。
最后,我們可以使用抽象工廠模式來創(chuàng)建不同風(fēng)格的角色和武器:
public class Main {public static void main(String[] args) {// 創(chuàng)建中世紀(jì)角色和武器CharacterFactory medievalFactory = new MedievalFactory();Character medievalCharacter = medievalFactory.createCharacter();Weapon medievalWeapon = medievalFactory.createWeapon();medievalCharacter.attack(medievalWeapon);medievalCharacter.defend();// 創(chuàng)建科幻角色和武器CharacterFactory sciFiFactory = new SciFiFactory();Character sciFiCharacter = sciFiFactory.createCharacter();Weapon sciFiWeapon = sciFiFactory.createWeapon();sciFiCharacter.attack(sciFiWeapon);sciFiCharacter.defend();}
}
在這個案例中,抽象工廠模式幫助我們通過CharacterFactory
接口創(chuàng)建不同風(fēng)格的角色和武器,使得客戶端代碼不需要知道具體的實現(xiàn)類。這樣,當(dāng)我們需要添加新的角色或武器時,只需要創(chuàng)建新的工廠類和相應(yīng)的角色和武器類即可,而無需修改現(xiàn)有的代碼。
6.1.3?單例模式(Singleton Pattern)
6.1.3.1 簡介
????????單例模式是一種創(chuàng)建型設(shè)計模式,它確保一個類只有一個實例,并提供一個全局訪問點。在單例模式中,類的構(gòu)造函數(shù)是私有的,這意味著其他類無法直接實例化該類。而是通過一個靜態(tài)方法或?qū)傩詠慝@取類的唯一實例。
6.1.3.2?優(yōu)缺點
單例模式是一種設(shè)計模式,其目的是確保一個類只有一個實例,并提供一個全局訪問點。
優(yōu)點:
- 在內(nèi)存中只有一個實例,節(jié)省了系統(tǒng)資源,提高了性能。
- 簡化了對象的管理,避免了重復(fù)創(chuàng)建和銷毀對象的開銷。
- 全局訪問點可以讓其他對象輕松地訪問單例對象。
缺點:
- 單例模式會增加代碼的復(fù)雜度,使代碼的可讀性和可維護(hù)性降低。
- 單例模式對擴(kuò)展不友好,如果未來需要擴(kuò)展單例對象的功能,可能需要修改已有的代碼。
- 單例模式的單一實例可能會成為系統(tǒng)的瓶頸,如果該實例需要進(jìn)行大量的計算或者處理大量的數(shù)據(jù),可能會成為系統(tǒng)的性能瓶頸。
- 單例模式不適用于多線程環(huán)境下,如果多個線程同時訪問單例對象,可能會導(dǎo)致競爭條件和數(shù)據(jù)不一致的問題,需要額外的代碼來處理線程安全性。
總結(jié)起來,單例模式在某些情況下可以提供一些好處,但也需要謹(jǐn)慎使用,以免引入不必要的復(fù)雜性和潛在的問題。
6.1.3.3?使用場景
單例模式的使用場景有以下幾種:
-
需要將某個類的實例化對象保持全局唯一,例如日志記錄器、數(shù)據(jù)庫連接池等。
-
需要頻繁創(chuàng)建和銷毀對象,且創(chuàng)建和銷毀對象的代價較大,單例模式可以避免頻繁創(chuàng)建和銷毀,提高性能。
-
需要訪問共享資源,例如線程池、線程管理器等。
-
需要確保系統(tǒng)中某個類只有一個實例存在,以便其他對象可以通過該實例訪問公共資源。
總之,單例模式適用于那些需要全局唯一的對象,并且需要在多個地方進(jìn)行訪問的場景。
6.1.3.4?使用案例
單例模式是一種創(chuàng)建型設(shè)計模式,用于確保一個類只有一個實例,并提供一個全局訪問點來訪問該實例。
以下是一個使用單例模式的Java案例:
public class Singleton {private static Singleton instance;// 私有構(gòu)造函數(shù),禁止外部直接創(chuàng)建對象private Singleton() {// 初始化代碼}// 公共靜態(tài)方法來獲取實例public static Singleton getInstance() {if (instance == null) {// 在第一次調(diào)用時,創(chuàng)建實例instance = new Singleton();}return instance;}// 其他業(yè)務(wù)方法public void showMessage() {System.out.println("Hello, World!");}
}
在上面的代碼中,Singleton類只有一個私有的靜態(tài)成員變量instance,用來存儲類的唯一實例。getInstance方法是公共的靜態(tài)方法,用來獲取該實例。
使用示例:
public class Main {public static void main(String[] args) {// 獲取Singleton實例Singleton singleton = Singleton.getInstance();// 調(diào)用業(yè)務(wù)方法singleton.showMessage(); // 輸出:Hello, World!}
}
在上面的示例中,我們通過Singleton.getInstance()方法獲取了Singleton類的唯一實例,并通過該實例調(diào)用了showMessage方法。
這種設(shè)計模式的好處是它確保任何時候都只有一個類的實例存在,避免了重復(fù)創(chuàng)建實例的開銷,并提供了一個全局訪問點來訪問該實例。
6.1.4?建造者模式(Builder Pattern)
6.1.4.1 簡介
建造者模式是一種創(chuàng)建型設(shè)計模式,它將對象的構(gòu)建過程與其表示分離,以便相同的構(gòu)建過程可以創(chuàng)建不同的表示。它允許你使用相同的構(gòu)建代碼來創(chuàng)建不同類型和表示的對象。
在建造者模式中,有一個建造者類,它負(fù)責(zé)創(chuàng)建對象的各個部分,并將它們組裝成一個完整的對象。該建造者類可以包含多個方法,每個方法用于構(gòu)建對象的一個部分。此外,還有一個指揮者類,它指導(dǎo)建造者類如何進(jìn)行構(gòu)建。
使用建造者模式的主要目的是將復(fù)雜對象的構(gòu)建過程與其表示分離,使其更加靈活和可擴(kuò)展。通過使用建造者模式,可以使構(gòu)建過程更加直觀,清晰,并且可以根據(jù)需要靈活地組裝不同類型和表示的對象。
建造者模式的主要角色包括:
- 產(chǎn)品類:表示被構(gòu)建的復(fù)雜對象。
- 抽象建造者類:定義構(gòu)建產(chǎn)品所需要的各個部分的抽象方法。
- 具體建造者類:實現(xiàn)抽象建造者類中定義的方法,具體構(gòu)建產(chǎn)品的各個部分。
- 指揮者類:指導(dǎo)具體建造者類如何進(jìn)行構(gòu)建,負(fù)責(zé)調(diào)用具體建造者類的方法來構(gòu)建產(chǎn)品。
6.1.4.2?優(yōu)缺點
建造者模式的優(yōu)缺點如下:
優(yōu)點:
- 建造者模式可以將一個復(fù)雜對象的構(gòu)建過程抽象出來,使得構(gòu)建過程與表示相分離,使得相同的構(gòu)建過程可以創(chuàng)建不同的表示。
- 可以更加精細(xì)地控制對象的構(gòu)建過程,使得構(gòu)建的對象可以符合特定的需求和約束。
- 可以簡化客戶端的使用,客戶端只需要指定需要構(gòu)建的類型和順序,而不需要關(guān)心具體的構(gòu)建過程。
缺點:
- 建造者模式需要定義一個獨立的建造者類,增加了系統(tǒng)的復(fù)雜度。
- 如果對象的結(jié)構(gòu)較為簡單,或者對象的構(gòu)建過程較為簡單,使用建造者模式可能會顯得繁瑣。
- 如果對象的部分屬性之間存在較強(qiáng)的關(guān)聯(lián)關(guān)系,而且需要以某種特定的順序來構(gòu)建對象,可能會增加建造者類的復(fù)雜度。
6.1.4.3?使用場景
建造者模式適用于以下場景:
-
當(dāng)創(chuàng)建對象的過程比較復(fù)雜,包含多個步驟、條件和子對象時,可以使用建造者模式來封裝對象的創(chuàng)建過程,并提供一個統(tǒng)一的接口。
-
當(dāng)需要創(chuàng)建的對象具有多種變化組合時,可以使用建造者模式來構(gòu)建不同組合的對象,而不需要創(chuàng)建大量的構(gòu)造函數(shù)或者使用復(fù)雜的參數(shù)列表。
-
當(dāng)需要在創(chuàng)建對象時進(jìn)行一些額外的處理或者初始化操作時,可以使用建造者模式來在創(chuàng)建對象的過程中執(zhí)行這些操作,而不需要在每個地方都寫重復(fù)的代碼。
-
當(dāng)需要創(chuàng)建一個不可變對象時,可以使用建造者模式來通過鏈?zhǔn)秸{(diào)用的方式逐步構(gòu)建對象的屬性,最后通過調(diào)用build方法來返回一個不可變的對象。
總的來說,建造者模式適用于需要創(chuàng)建復(fù)雜對象、有多種組合方式或者需要在創(chuàng)建過程中進(jìn)行一些額外處理的場景。
6.1.4.4?使用案例
????????建造者模式是一種創(chuàng)建型設(shè)計模式,它允許你通過一步一步地構(gòu)造復(fù)雜對象。它將構(gòu)造過程和表示對象的內(nèi)部結(jié)構(gòu)分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
????????在Java中,可以使用建造者模式來創(chuàng)建復(fù)雜的對象,避免構(gòu)造函數(shù)的參數(shù)過多或使用過長的參數(shù)列表來構(gòu)造對象。下面是一個使用建造者模式的Java案例。
????????假設(shè)有一個汽車類Car,它有多個可選屬性,例如顏色、引擎類型、座位數(shù)量等。我們希望能夠方便地創(chuàng)建不同配置的汽車對象。首先,我們定義Car類:
public class Car {private String color;private String engineType;private int seatCount;// 私有構(gòu)造函數(shù),只能通過Builder來創(chuàng)建Car對象private Car(Builder builder) {this.color = builder.color;this.engineType = builder.engineType;this.seatCount = builder.seatCount;}// Getter方法public String getColor() {return color;}public String getEngineType() {return engineType;}public int getSeatCount() {return seatCount;}// 內(nèi)部靜態(tài)Builder類,用于構(gòu)建Car對象public static class Builder {private String color;private String engineType;private int seatCount;// 設(shè)置必需的參數(shù)public Builder(String color, String engineType) {this.color = color;this.engineType = engineType;}// 設(shè)置可選參數(shù)public Builder seatCount(int seatCount) {this.seatCount = seatCount;return this;}// 構(gòu)建Car對象public Car build() {return new Car(this);}}
}
現(xiàn)在,我們可以使用Builder類來創(chuàng)建不同配置的Car對象。例如:
Car car1 = new Car.Builder("red", "V8").seatCount(4).build();
Car car2 = new Car.Builder("blue", "electric").seatCount(2).build();
上述代碼中,我們首先通過Builder類創(chuàng)建一個Builder對象,然后使用鏈?zhǔn)秸{(diào)用來設(shè)置可選參數(shù),最后調(diào)用build()方法來構(gòu)建Car對象。
使用建造者模式的好處是,可以按需設(shè)置對象的屬性,而不必關(guān)心構(gòu)造函數(shù)的參數(shù)順序或參數(shù)類型。這樣可以使代碼更加清晰、易讀和易于維護(hù)。
6.1.5?原型模式(Prototype Pattern)
6.1.5.1 簡介
????????原型模式是一種創(chuàng)建型設(shè)計模式,它通過復(fù)制現(xiàn)有對象來生成新對象,而無需顯式地使用構(gòu)造函數(shù)。在原型模式中,通過克隆一個已經(jīng)存在的對象的原型來創(chuàng)建新的對象,并且可以根據(jù)需要進(jìn)行參數(shù)的修改。
????????該模式的主要目的是盡量減少對象的創(chuàng)建,通過復(fù)制已有對象的原型來創(chuàng)建新對象,可以在某些場景下提升性能和效率。
原型模式通常包含以下幾個角色:
-
原型接口/抽象類(Prototype):定義克隆方法的接口或抽象類,所有具體原型類都要實現(xiàn)或繼承此接口。
-
具體原型類(ConcretePrototype):實現(xiàn)克隆方法的具體原型類。
-
客戶端(Client):使用原型對象的客戶端,在需要創(chuàng)建新對象時,通過克隆原型對象來創(chuàng)建。
6.1.5.2?優(yōu)缺點
原型模式的優(yōu)點:
- 簡化對象的創(chuàng)建過程:原型模式通過復(fù)制現(xiàn)有對象來創(chuàng)建新對象,避免了創(chuàng)建對象的復(fù)雜的初始化步驟,使得對象的創(chuàng)建過程更加簡單。
- 提高性能:原型模式通過復(fù)制現(xiàn)有對象來創(chuàng)建新對象,避免了對象的重新初始化,可以提高創(chuàng)建對象的效率。
- 動態(tài)添加和刪除對象:原型模式允許動態(tài)地添加和刪除原型對象,方便了對象的管理。
- 隱藏創(chuàng)建過程:原型模式將對象的創(chuàng)建過程封裝在原型類中,客戶端只需要通過復(fù)制操作即可獲取新對象,不需要關(guān)心對象的創(chuàng)建細(xì)節(jié)。
原型模式的缺點:
- 需要對原型對象進(jìn)行克隆操作:使用原型模式需要在每個具體原型類中實現(xiàn)克隆操作,如果對象的成員變量較多或者成員變量為引用類型,需要對每個引用對象進(jìn)行深拷貝,實現(xiàn)克隆操作可能會比較復(fù)雜。
- 可能導(dǎo)致循環(huán)引用問題:在克隆操作中,如果存在循環(huán)引用,可能導(dǎo)致克隆對象中出現(xiàn)重復(fù)的對象,影響對象的正確性。
- 可能導(dǎo)致性能問題:使用原型模式創(chuàng)建對象時,會通過復(fù)制操作來創(chuàng)建新對象,如果對象的復(fù)制過程比較復(fù)雜,可能會導(dǎo)致性能問題。
6.1.5.3?使用場景
原型模式的主要使用場景如下:
-
當(dāng)一個對象的創(chuàng)建過程比較復(fù)雜或者耗時時,可以使用原型模式來復(fù)制一個已經(jīng)存在的對象,然后進(jìn)行適當(dāng)?shù)男薷?#xff0c;以減少對原對象的創(chuàng)建過程和資源消耗。
-
當(dāng)一個對象需要在不同的場景中多次創(chuàng)建時,可以使用原型模式來復(fù)制一個已有的對象,然后進(jìn)行適當(dāng)?shù)男薷暮投ㄖ?#xff0c;以滿足不同場景的需求。
-
當(dāng)一個對象的創(chuàng)建過程需要依賴于其他對象或者配置信息時,可以使用原型模式來復(fù)制一個已有的對象,然后進(jìn)行適當(dāng)?shù)男薷暮团渲?#xff0c;以簡化對象的創(chuàng)建過程。
-
當(dāng)一個對象的創(chuàng)建過程需要根據(jù)運(yùn)行時的條件決定時,可以使用原型模式來復(fù)制一個已有的對象,然后進(jìn)行適當(dāng)?shù)男薷暮投ㄖ?#xff0c;以根據(jù)不同的條件創(chuàng)建不同的對象。
總之,原型模式適用于對象創(chuàng)建過程復(fù)雜、耗時或者需要重復(fù)創(chuàng)建的場景,可以通過復(fù)制已有對象來簡化和加快對象的創(chuàng)建過程。
6.1.5.4?使用案例
原型模式是一種創(chuàng)建型設(shè)計模式,它通過復(fù)制現(xiàn)有對象的原型來創(chuàng)建新的對象。與使用new關(guān)鍵字創(chuàng)建新對象相比,原型模式更加靈活和高效。
在Java中,實現(xiàn)原型模式主要涉及以下幾個步驟:
- 創(chuàng)建一個原型接口(或抽象類),聲明一個克隆方法clone(),用于復(fù)制對象。
public interface Prototype {Prototype clone();
}
? ? ? ? 2. 實現(xiàn)原型接口的具體類,該類需要實現(xiàn)clone()方法來復(fù)制對象。
public class ConcretePrototype implements Prototype {private String name;public ConcretePrototype(String name) {this.name = name;}public Prototype clone() {return new ConcretePrototype(name);}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
? ? ? ? 3. 在客戶端代碼中使用原型對象來創(chuàng)建新對象,而無需顯式地調(diào)用構(gòu)造函數(shù)。
public class Client {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype("Prototype");// 使用原型對象創(chuàng)建新對象ConcretePrototype clone = (ConcretePrototype) prototype.clone();clone.setName("Cloned Prototype");System.out.println("Original Prototype: " + prototype.getName());System.out.println("Cloned Prototype: " + clone.getName());}
}
以上代碼中,我們定義了一個原型接口Prototype
,其中包含了一個clone()
方法用于復(fù)制對象。然后我們實現(xiàn)了一個具體的原型類ConcretePrototype
,該類實現(xiàn)了Prototype
接口,并復(fù)寫了clone()
方法來創(chuàng)建新對象。
在客戶端代碼中,我們首先創(chuàng)建一個原型對象prototype
,然后使用原型對象來創(chuàng)建新對象clone
。通過調(diào)用clone()
方法,clone
對象將擁有和prototype
相同的屬性值,并且它們是兩個獨立的對象。
最后,我們打印輸出了原型對象和克隆對象的名稱,可以看到它們的名稱分別為"Prototype"和"Cloned Prototype"。這證明了原型模式的成功復(fù)制和創(chuàng)建對象的能力。
原型模式在Java中的應(yīng)用非常廣泛,特別是在需要創(chuàng)建大量相似對象的場景下,原型模式能夠提供一種高效的解決方案。通過復(fù)制現(xiàn)有對象的原型,無需重復(fù)創(chuàng)建新對象,從而提高性能和代碼的可維護(hù)性。
6.2?結(jié)構(gòu)型模式(Structural)
詳見《Java設(shè)計模式大全:23種常見的設(shè)計模式詳解(二)》
6.3?行為型模式(Behavioral)
詳見《Java設(shè)計模式大全:23種常見的設(shè)計模式詳解(三)》
7、結(jié)語
????????文章至此,已接近尾聲!希望此文能夠?qū)Υ蠹矣兴鶈l(fā)和幫助。同時,感謝大家的耐心閱讀和對本文檔的信任。在未來的技術(shù)學(xué)習(xí)和工作中,期待與各位大佬共同進(jìn)步,共同探索新的技術(shù)前沿。最后,再次感謝各位的支持和關(guān)注。您的支持是作者創(chuàng)作的最大動力,如果您覺得這篇文章對您有所幫助,請考慮給予一點打賞。