工廠模式 詳解 設計模式

工廠模式

其主要目的是封裝對象的創建過程,使客戶端代碼和具體的對象實現解耦。這樣子就不用每次都new對象,更換對象的話,所有new對象的地方也要修改,違背了開閉原則(對擴展開放,對修改關閉)。使用工廠來生產對象,更換對象也直接在工廠更換即可。

工廠模式的主要好處包括:

  1. 解耦合:工廠模式將對象的創建過程與客戶端代碼分離,客戶端不需要知道具體的對象是如何創建的,只需要通過工廠方法獲取對象即可,從而降低了代碼之間的耦合度。
  2. 靈活性:由于工廠負責創建對象,客戶端可以通過工廠方法獲取不同的對象實例,而無需關心具體的實現細節,從而提高了系統的靈活性。
  3. 可擴展性:如果需要添加新的產品類型,只需在工廠中添加相應的產品創建邏輯,而不需要修改客戶端代碼,這樣可以很方便地擴展系統的功能。
  4. 統一管理:工廠模式將對象的創建集中在一個地方,便于統一管理和維護,提高了代碼的可維護性。

使用場景:

  • 當一個系統需要創建多個類型的對象,并且這些對象之間存在著共同的接口時,可以考慮使用工廠模式。
  • 當客戶端不需要知道具體的對象是如何創建的,只需要獲取對象實例時,可以使用工廠模式。
  • 當系統需要動態地決定創建哪種類型的對象時,可以使用工廠模式。

工廠模式包含以下幾個核心角色:

  • 抽象產品(Abstract Product):**定義了產品的共同接口或抽象類。**它可以是具體產品類的父類或接口,規定了產品對象的共同方法
  • 具體產品(Concrete Product):實現了抽象產品接口,定義了具體產品的特定行為和屬性。
  • 抽象工廠(Abstract Factory):聲明了創建產品的抽象方法,可以是接口或抽象類。它可以有多個方法用于創建不同類型的產品。
  • 具體工廠(Concrete Factory):實現了抽象工廠接口,負責實際創建具體產品的對象

這里介紹三種工廠

  • 簡單工廠模式(不屬于GOF的23種經典設計模式)
  • 工廠方法模式
  • 抽象工廠模式

簡單工廠模式

簡單工廠不是一種設計模式,反而比較像是一種編程習慣。

結構:

簡單工廠包含如下角色:

  • 抽象產品 :定義了產品的規范,描述了產品的主要特性和功能。
  • 具體產品 :實現或者繼承抽象產品的子類
  • 具體工廠 :提供了創建產品的方法,調用者通過該方法來獲取產品。

使用場景

  • 當對象的創建邏輯相對簡單,并且不需要頻繁地進行變更時,可以考慮使用簡單工廠模式。
  • 在客戶端只知道所需產品的名稱或類型,而不需要關心產品的創建過程時,可以使用簡單工廠模式。

實現思路:

在這里插入圖片描述

// 抽象產品接口
interface Product {      void show();
}// 具體產品類A
class ConcreteProductA implements Product {@Overridepublic void show() {System.out.println("This is product A.");}
}// 具體產品類B
class ConcreteProductB implements Product {@Overridepublic void show() {System.out.println("This is product B.");}
}// 簡單工廠類
class SimpleFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ConcreteProductA();} else if ("B".equals(type)) {return new ConcreteProductB();}return null;}
}// 客戶端
public class Client {public static void main(String[] args) {Product productA = SimpleFactory.createProduct("A");productA.show();Product productB = SimpleFactory.createProduct("B");productB.show();}
}

上面的工廠類創建對象的功能定義為靜態的,這個屬于是靜態工廠模式,當然你也可以不設置為靜態的。

優缺點:

優點:

  • 簡單工廠模式中,客戶端通過工廠類的靜態方法來獲取產品實例,而不需要直接實例化具體產品類。如果要實現新產品直接修改工廠類,而不需要在原代碼中修改。

缺點:

  • 工廠類負責創建所有產品,因此如果系統需要添加新的產品類型,需要修改工廠類,違反了開放封閉原則。

工廠方法模式

使用工廠方法模式可以完美的解決簡單工廠模式的缺點,完全遵循開閉原則。

概念

定義一個用于創建對象的接口,讓子類決定實例化哪個產品類對象。工廠方法使一個產品類的實例化延遲到其工廠的子類。

結構

工廠方法模式的主要角色:

  • 抽象工廠(Abstract Factory):提供了創建產品的接口,調用者通過它訪問具體工廠的工廠方法來創建產品。
  • 具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的創建。
  • 抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能。
  • 具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它同具體工廠之間一一對應。

圖例

使用工廠方法模式對上例進行改進:
在這里插入圖片描述

工廠方法模式適用于需要創建一系列相關對象的情況

// 抽象產品接口
interface Product {void show();
}// 具體產品類A
class ConcreteProductA implements Product {@Overridepublic void show() {System.out.println("This is product A.");}
}// 具體產品類B
class ConcreteProductB implements Product {@Overridepublic void show() {System.out.println("This is product B.");}
}// 抽象工廠類
interface Factory {Product createProduct();
}// 具體工廠類A,負責創建產品A
class ConcreteFactoryA implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductA();}
}// 具體工廠類B,負責創建產品B
class ConcreteFactoryB implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductB();}
}// 客戶端
public class Client {public static void main(String[] args) {Factory factoryA = new ConcreteFactoryA();Product productA = factoryA.createProduct();productA.show();Factory factoryB = new ConcreteFactoryB();Product productB = factoryB.createProduct();productB.show();}
}

于是乎要增加產品類時只要相應地增加工廠類,不需要修改工廠類的代碼了,這樣就解決了簡單工廠模式的缺點。

使用場景

  • 當需要創建的對象是一個具體的產品,但是不確定具體產品的類型時,可以使用工廠方法模式。
  • 在工廠類中定義一個創建產品的抽象方法,由子類負責實現具體產品的創建過程,從而實現了產品的創建和客戶端的解耦

優缺點

優點:

  • 工廠方法模式中,客戶端通過調用工廠類的方法來創建產品,具體產品的創建邏輯由子類實現,不同的產品由不同的工廠子類負責創建。
  • 工廠方法模式符合開放封閉原則,因為客戶端可以通過新增工廠子類來添加新的產品類型,而無需修改原有的代碼。

缺點:

  • 每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的復雜度。

抽象工廠模式

抽象工廠模式通常涉及一族相關的產品,每個具體工廠類負責創建該族中的具體產品。

使用場景

  • 當一個系統需要創建一系列相互關聯或相互依賴的產品對象時,可以考慮使用抽象工廠模式。
  • 抽象工廠模式提供了一個創建一組相關或相互依賴對象的接口,客戶端可以通過該接口來創建產品族中的不同產品,而不需要關心具體的產品實現。

所以由此也可看出,普通工廠模式,工廠方法模式都只是單一產品類的工廠;而很多時候我們需要綜合性的,需要生產多等級產品的工廠。下圖所示橫軸是產品等級,也就是同一類產品;縱軸是產品族,也就是同一品牌的產品,同一品牌的產品產自同一個工廠:

在這里插入圖片描述

結構

抽象工廠模式的主要角色如下:

  • 抽象工廠(Abstract Factory):提供了創建產品的接口,它包含多個創建產品的方法,可以創建多個不同等級的產品。
  • 具體工廠(Concrete Factory):主要是實現抽象工廠中的多個抽象方法,完成具體產品的創建。
  • 抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。
  • 具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它同具體工廠之間是多對一的關系。

請添加圖片描述

代碼案例:

// 抽象產品接口
interface Product {void show();
}// 具體產品類A
class ConcreteProductA implements Product {@Overridepublic void show() {System.out.println("This is product A.");}
}// 具體產品類B
class ConcreteProductB implements Product {@Overridepublic void show() {System.out.println("This is product B.");}
}// 抽象工廠接口
interface AbstractFactory {Product createProductA();Product createProductB();
}// 具體工廠類,負責創建產品A和產品B
class ConcreteFactory implements AbstractFactory {@Overridepublic Product createProductA() {return new ConcreteProductA();}@Overridepublic Product createProductB() {return new ConcreteProductB();}
}// 客戶端
public class Client {public static void main(String[] args) {AbstractFactory factory = new ConcreteFactory();Product productA = factory.createProductA();productA.show();Product productB = factory.createProductB();productB.show();}
}
  • 使用場景

    • 當需要創建的對象是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等。
    • 系統中有多個產品族,但每次只使用其中的某一族產品。如有人只喜歡穿某一個品牌的衣服和鞋。
    • 系統中提供了產品的類庫,且所有產品的接口相同,客戶端不依賴產品實例的創建細節和內部結構。

優缺點

優點:

當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象。

缺點:

當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改。

模式擴展 (利用反射機制來創建對象)

簡單工廠+配置文件解除耦合

可以通過工廠模式+配置文件的方式解除工廠對象和產品對象的耦合。

通過使用配置文件,將創建對象的參數存儲在外部配置文件中,可以在不修改客戶端代碼的情況下,通過修改配置文件來改變對象的創建方式。這樣就可以實現對創建邏輯的解耦合,客戶端不需要知道具體的創建方式,只需要從工廠類獲取對象即可。

具體實現步驟如下:

  1. 在配置文件中配置需要創建的對象的類名或者類型。
  2. 在簡單工廠類中讀取配置文件,并根據配置的信息來創建對應的對象。

假設有一個配置文件 config.properties,內容如下:

product.type=ConcreteProductA

創建簡單工廠類 SimpleFactory.java,用于讀取配置文件并根據配置創建對象:

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;public class SimpleFactory { public static Product createProduct() {Properties properties = new Properties();try (InputStream inputStream = SimpleFactory.class.getResourceAsStream("config.properties")) {properties.load(inputStream);String productType = properties.getProperty("product.type");if ("ConcreteProductA".equals(productType)) {return new ConcreteProductA();} else if ("ConcreteProductB".equals(productType)) {return new ConcreteProductB();}} catch (IOException e) {e.printStackTrace();}return null;}
}

在日常開發中,設計模式中的一些常用模式包括:

  1. 單例模式 (Singleton):用于確保一個類只有一個實例,并提供全局訪問點,例如數據庫連接池、日志系統等。
  2. 工廠模式 (Factory):用于創建對象的接口,但是由子類決定要實例化的類是哪一個。例如,可以用工廠模式創建各種類型的文件解析器。
  3. 觀察者模式 (Observer):用于建立對象之間一對多的依賴關系,當一個對象的狀態發生變化時,所有依賴它的對象都會得到通知。例如,GUI界面中的事件監聽器。
  4. 策略模式 (Strategy):定義一系列算法,將每個算法封裝起來,并使它們可以互換。例如,根據用戶的選擇使用不同的支付策略。
  5. 裝飾器模式 (Decorator):動態地給一個對象添加一些額外的職責。例如,在圖像處理中可以使用裝飾器來添加濾鏡效果。
  6. 模板方法模式 (Template Method):定義一個算法的骨架,允許子類為一個或多個步驟提供實現。例如,在構建流程中的各個階段都有固定的步驟,但是具體實現可能不同。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711078.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711078.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711078.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Gson解析數組類型的JSON字符串

要使用Gson解析數組類型的JSON字符串,首先需要創建一個Java類來表示這個數組中的數據類型。例如,假設我們要解析的JSON數組如下: [{"name": "John Doe","age": 35},{"name": "Jane Smith"…

win中刪除不掉的文件,火絨粉碎刪除親測有效

看網上的 win R 然后終端輸入什么刪除的,照做了都沒有刪掉 有火絨的可以試試: 拖進去就刪掉了 很好使

選項 打光 試題總結

試題1 被測物體100100mm,精度要求被測物體 ,精度要求0.1mm,相機距被測物體在200~320mm之間,要求選擇合適的相機和鏡頭? 分析如下: 通常我們用的相機靶面是4:3 的所以我們要用短邊來計算視場&am…

Jmeter系列(5)線程數到底能設置多大

疑惑 一臺設備的線程數到底可以設置多大? 線程數設置 經過一番搜索找到了這樣的答案: Linux下,2g的 java內存,1m 的棧空間,最大啟動線程數2000線程數建議不超過1000jmeter 能啟動多少線程,由你的堆內存…

CSS常用選擇器及注意事項

CSS選擇器是CSS中的基本概念,用于選擇頁面上要樣式化的元素。下面詳細介紹CSS中所有的選擇器、使用方法及注意事項。 1. 基本選擇器 通用選擇器(Universal Selector):*,選擇頁面上的所有元素。元素類型選擇器&#x…

Tomcat 下部署若依單體應用可觀測最佳實踐

實現目標 采集指標信息采集鏈路信息采集日志信息采集 RUM 信息會話重放 即用戶訪問前端的一系列過程的會話錄制信息,包括點擊某個按鈕、操作界面、停留時間等,有助于客戶真是意圖、操作復現 版本信息 Tomcat (9.0.81)Springboot(2.6.2)JDK (>8)DDT…

【Redis筆記】Redis消息隊列方案

Reids消息隊列(Message Queue) 消息隊列 是指利用 高效可靠 的 消息傳遞機制 進行與平臺無關的 數據交流,并基于數據通信來進行分布式系統的集成。 消息隊列具有 低耦合、可靠投遞、廣播、流量控制、最終一致性 等功能。 常見的消息隊列 有 …

ensp路由器將不同網絡連通在一起

1.拓撲結構信息如下 二層交換機:lsw2,lsw3,lsw5,lsw6 不進行ip配置,只是定義vlan,和主機標注的保持一致,向下連接pc用access,向上連接路由交換機用trunk lsw2配置信息如下圖 定義vlan,設置各個連接口的方式…

tcpdump 常用用法

簡要記錄下tcpdump用法 監控某個ip上的某個端口的流量 tcpdump -i enp0s25 tcp port 5432 -nn -S 各個參數作用 -i enp0s25 指定抓包的網卡是enp0s25 -nn 顯示ip地址和數字端口 ,如果只 -n 則顯示ip,但是端口為services文件中的服務名 如果一個…

用python寫一個自動化部署工具

效果 起因 現在springboot項目的自動化部署已經非常普遍,有用Jenkins的,有用git鉤子函數的,有用docker的…等等。這段時間在玩python,想著用python實現自動化部署,即能鍛煉下編碼能力,又方便運維。于是開始…

每日學習總結20240228

每日總結 20240228 1.獲取系統命令執行結果 #include <stdio.h>#define TRUE 1 #define FALSE 0int get_system_cmd_result(const char *command, char *buffer, int bufferLen) {FILE *pipe popen(command, "r");if (pipe NULL) {return FALSE;}while (f…

HTML-表格、表單和CSS初識,選擇器,書寫規范

&#xff11;. 表格標簽 &#xff11;.&#xff11;創建表格 表格標簽是一種用來處理&#xff0c;顯示表格式數據的常用標簽。 注意&#xff1a; &#xff11;. tr 用于定義表格中的一行&#xff0c;必須嵌套在 table標簽中&#xff0c;在 table中包含幾對 tr&#xff0c;就有…

實用指南:SOLIDWORKS數據失真問題的解決之道

在數據處理和模擬計算的過程中&#xff0c;數據失真是一個常見的挑戰。數據失真指的是由于計算機或人為操作導致的原始數據與計算結果或實際情況之間的偏差。特別是在使用SOLIDWORKS這類工程設計軟件時&#xff0c;數據失真可能由多種因素引起&#xff0c;如軟件版本老舊、設置…

AI大模型-啟航

文章目錄 什么是大模型&#xff1f;&#xff08;大體現在參數量巨大&#xff09;大模型將會改變那些行業&#xff08;大模型有哪些作用&#xff1f;&#xff09;如何搞數據訓練模型&#xff1f;LangChain帶來的技術變革LangChain架構 什么是大模型&#xff1f;&#xff08;大體…

九、GG bond的邏輯運算

描述 GG bond想要鍛煉自己的邏輯能力&#xff0c;于是輸入了兩個整型變量x和y&#xff0c;分別判斷它們的與、或、非關系&#xff0c;你能幫他輸出x與y&#xff0c;x或y&#xff0c;非x&#xff0c;非y的值嗎&#xff1f; 輸入描述&#xff1a; 輸入兩個整數x和y&#xff0c…

Vue+SpringBoot打造不良郵件過濾系統

目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 系統用戶模塊2.2 收件箱模塊2.3 發件箱模塊2.4 垃圾箱模塊2.5 回收站模塊2.6 郵箱過濾設置模塊 三、實體類設計3.1 系統用戶3.2 郵件3.3 其他實體 四、系統展示五、核心代碼5.1 查詢收件箱檔案5.2 查詢回收站檔案5.3 新…

Linux學習-etcdctl安裝

etcdctl3.5下載鏈接 1. 先通過上面鏈接下載gz包2. 解壓 [rootk8s-master ~]# tar xf etcd-v3.5.11-linux-amd64.tar.gz [rootk8s-master etcd-v3.5.11-linux-amd64]# ls Documentation etcd etcdctl etcdutl README-etcdctl.md README-etcdutl.md README.md READMEv2-e…

圖像分割 - 查找圖像的輪廓(cv2.findContours函數)

1、前言 輪廓,是指圖像中或者物體的外邊緣線條。在簡單的幾何圖形中,圖形的輪廓是由平滑的線條構成,容易被識別。但不規則的圖形或者生活中常見的物體輪廓復雜,識別起來比較困難 2、findContours函數 這里先介紹函數的參數,具體的含義會在下面實驗中闡述 opencv 提供的輪…

『大模型筆記』自用的“科技文章翻譯 GPT”和它的 Prompt

自用的“科技文章翻譯 GPT”和它的 Prompt 你是一位精通簡體中文的專業翻譯,尤其擅長將專業學術論文翻譯成淺顯易懂的科普文章。請你幫我將以下英文段落翻譯成中文,風格與中文科普讀物相似。規則: - 翻譯時要準確傳達原文的事實和背景。 - 即使上意譯也要保留原始段落格式,…

每天一個數據分析題(一百八十四)

在下列哪種情況下線性回歸模型不適合代替邏輯回歸模型&#xff1f; A. 預測的目標變量是連續型的并且分布范圍不受限制 B. 預測的目標變量是二元的并且服從二項分布 C. 自變量與因變量之間的關系可以假設為線性關系 D. 需要預測客戶的具體購買金額 題目來源于CDA模擬題庫 …