?作者簡介:大家好,我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式,持續分享Java技術內容。
🍎個人主頁:Meteors.的博客
💞當前專欄:設計模式
?特色專欄:知識分享
🥭本文內容:23種設計模式——抽象工廠模式(Abstract Factory Pattern)
📚 ** ps **? :閱讀文章如果有問題或者疑惑,歡迎在評論區提問或指出。
目錄
一. 背景
二. 介紹
三.?核心角色
四. 代碼示例
1.??抽象產品 & 具體產品?
2.?抽象工廠 & 具體工廠?
3.?客戶端代碼?
五.??與簡單工廠、工廠方法的區別
六. 抽象工廠模式的優缺點
七. 總結與應用場景
一. 背景
對于工廠方法模式,會有一個工廠類里面有一個抽象工廠方法并且返回類型是一個接口基類(大白話講就是這個方法創建了一個基類的不同實現類,如基類為按鈕,我們就可以通過這個方法創建圓形按鈕或者方形按鈕);
但如果現在有個界面,不僅僅要創建不同類型的按鈕,還要創建不同類型的文本框、字體......這種情況怎么辦?其實這個時候我們就可以創建一個抽象工廠模式(就是這個界面),里面有多個抽象工廠方法(創建按鈕的、創建文本框的、創建字體的......)。抽象工廠。它本質上是??多個工廠方法的組合,這些方法共同生產一個產品族。
二. 介紹
抽象工廠模式??是一種創建型設計模式,它提供一個接口,用于創建??相關或依賴對象??的??家族??,而不需要明確指定具體類。
你可以將其理解為“工廠的工廠”。客戶端代碼不直接通過
new
來實例化具體的產品,而是通過一個抽象的接口來創建一整組相關的產品。這使得客戶端代碼與具體的產品類解耦,并且能確保所創建的產品是相互兼容的。
三.?核心角色
- ??抽象工廠??:聲明一個創建??一族產品??(多個不同產品等級)的接口,包含多個創建產品的方法,如?
createButton()
,?createTextBox()
。- ??具體工廠??:實現抽象工廠的接口,負責創建某一族具體的產品。例如,
WindowsFactory
?創建 Windows 風格的按鈕和文本框,MacFactory
?創建 Mac 風格的按鈕和文本框。- ??抽象產品??:聲明每種產品類型的接口。例如,
Button
?和?TextBox
。- ??具體產品??:實現抽象產品接口,由具體工廠創建。例如,
WindowsButton
,?MacButton
,?WindowsTextBox
,?MacTextBox
。
四. 代碼示例
用一個界面為例:
1.??抽象產品 & 具體產品?
// 抽象產品:按鈕 public interface Button {void render();void onClick(); }// 具體產品:Windows按鈕 public class WindowsButton implements Button {@Overridepublic void render() {System.out.println("渲染一個Windows風格的按鈕");}@Overridepublic void onClick() {System.out.println("Windows按鈕被點擊!");} }// 具體產品:Mac按鈕 public class MacButton implements Button {@Overridepublic void render() {System.out.println("渲染一個Mac風格的按鈕");}@Overridepublic void onClick() {System.out.println("Mac按鈕被點擊!");} }// 抽象產品:文本框 public interface TextBox {void render(); }// 具體產品:Windows文本框 public class WindowsTextBox implements TextBox {@Overridepublic void render() {System.out.println("渲染一個Windows風格的文本框");} }// 具體產品:Mac文本框 public class MacTextBox implements TextBox {@Overridepublic void render() {System.out.println("渲染一個Mac風格的文本框");} }
2.?抽象工廠 & 具體工廠?
// 抽象工廠 public interface GUIFactory {Button createButton();TextBox createTextBox(); }// 具體工廠:Windows工廠 public class WindowsFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic TextBox createTextBox() {return new WindowsTextBox();} }// 具體工廠:Mac工廠 public class MacFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacButton();}@Overridepublic TextBox createTextBox() {return new MacTextBox();} }
3.?客戶端代碼?
客戶端代碼只依賴抽象工廠和抽象產品,從而與具體平臺解耦。
public class Application {private Button button;private TextBox textBox;// 通過構造器注入一個具體的工廠public Application(GUIFactory factory) {button = factory.createButton();textBox = factory.createTextBox();}public void renderUI() {button.render();textBox.render();}public static void main(String[] args) {// 根據配置或環境決定使用哪種工廠GUIFactory factory;String osName = System.getProperty("os.name").toLowerCase();if (osName.contains("win")) {factory = new WindowsFactory();} else {factory = new MacFactory();}Application app = new Application(factory);app.renderUI();// 輸出:// 如果是Windows: // 渲染一個Windows風格的按鈕// 渲染一個Windows風格的文本框// 如果是Mac:// 渲染一個Mac風格的按鈕// 渲染一個Mac風格的文本框} }
五.??與簡單工廠、工廠方法的區別
特征 簡單工廠 工廠方法 抽象工廠 ??核心思想?? 由一個工廠類根據傳入的參數,??靜態??地決定創建哪一種產品。 定義一個創建對象的接口,但讓??子類??決定實例化哪一個類。 提供一個接口,用于創建??相關或依賴對象??的??家族??,而不指定具體類。 ??工廠角色?? 一個??具體工廠??類,包含創建所有產品的邏輯。 一個??抽象工廠??接口和多個??具體工廠??實現(每個對應一個產品)。 一個??抽象工廠??接口和多個??具體工廠??實現(每個對應一族產品)。 ??產品維度?? ??一個產品等級??(例如:只有按鈕)。 ??一個產品等級??(例如:只有按鈕)。 ??多個產品等級??(例如:按鈕、文本框、復選框等??一套產品??)。 ??擴展性?? ??違反開閉原則??。要新增產品,必須修改工廠類的邏輯。 ??符合開閉原則??。要新增產品,只需新增一個具體工廠即可。 ??符合開閉原則??。但要新增一個產品族(如Linux主題)很容易,??新增一個產品等級??(如新增Slider滑塊)很困難,需要修改所有工廠接口和類。 ??復雜度/適用場景?? 簡單,適用于產品類型較少且幾乎不會變化的場景。 適中,適用于產品結構單一但需要靈活擴展的場景。 復雜,適用于需要創建一整系列相互關聯、相互依賴的產品,并保證它們兼容的場景。 演進關系(從簡單到復雜):
- .簡單工廠??:如果你只有一個產品(比如只有
Button
),用簡單工廠就夠了。- 工廠方法??:當你的產品變得復雜,或者你希望擴展時不修改原有代碼(比如未來要加
LinuxButton
),你就為每種按鈕建立一個專門的工廠。- 抽象工廠??:當你不止有按鈕,還有文本框、復選框等??一整套需要搭配使用??的產品時,工廠方法就不夠了。你需要一個能創建??整套產品??的工廠,這就是抽象工廠。它本質上是??多個工廠方法的組合??,這些方法共同生產一個產品族。
六. 抽象工廠模式的優缺點
??優點:??
- 保證了產品的兼容性??:確保客戶端始終只使用同一產品族中的對象。你不會把一個Windows按鈕和一個Mac文本框混在一起用。
- 解耦客戶端與具體產品??:客戶端代碼只面向抽象接口編程,使得切換整個產品族變得非常容易(只需換一個具體工廠)。
- 符合開閉原則??:易于擴展新的產品族(如新增一個
LinuxFactory
)。??缺點:??
- 難以支持新的產品種類??:這是最大的缺點。如果要為所有工廠增加一個新的產品(如在產品族中增加
Slider
滑塊),就需要修改抽象工廠接口GUIFactory
,這會導致所有具體工廠類(WindowsFactory
,?MacFactory
)都需要被修改,違反了開閉原則。- 增加了系統的復雜性??:類會變得非常多(n個產品族 * m個產品等級 = n*m個類)。
七. 總結與應用場景
??抽象工廠模式的核心是創建產品族。??
??典型應用場景:??
- 系統需要獨立于其產品的創建、組合和表示時??。
- ??系統需要配置多個產品族中的某一個時??。
- 需要強調一系列相關產品對象的設計以便進行聯合使用時??。
- 希望提供一個產品類庫,但只想暴露它們的接口而不是實現時??。
??經典例子:??
- ?跨平臺GUI開發??(如Java AWT/Swing, QT)。
- 數據庫訪問層??:
Connection
,?Command
,?DataAdapter
?構成一個產品族,可以輕松在?SqlServerFactory
?和?OracleFactory
?之間切換。- 游戲開發??:為不同風格(科幻、中世紀)的場景創建一套主題資源(建筑、士兵、植被)。
- ??日志記錄器??:創建一套相關的日志組件(記錄器、格式化器、附加器)。
最后,
? ? ? ? 其它設計模式會陸續更新,希望文章對你有所幫助!