深入理解設計模式:工廠模式、單例模式

深入理解設計模式:工廠模式、單例模式

設計模式是軟件開發中解決常見問題的可復用方案。本文將詳細介紹兩種種重要的創建型設計模式:工廠模式、單例模式,并提供Java實現示例。

一、工廠模式

工廠模式是一種創建對象的設計模式,它提供了一種創建對象的最佳方式,而無需向客戶端暴露創建邏輯。

1.1 簡單工廠模式

簡單工廠模式由一個工廠類負責創建所有產品。

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

1.2 工廠方法模式

工廠方法模式將實際創建對象的責任委托給子類。

// 產品接口
interface Product {void operation();
}// 具體產品A
class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}// 具體產品B
class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}// 工廠接口
interface Factory {Product createProduct();
}// 具體工廠A
class ConcreteFactoryA implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductA();}
}// 具體工廠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.operation();Factory factoryB = new ConcreteFactoryB();Product productB = factoryB.createProduct();productB.operation();}
}

1.3 抽象工廠模式

抽象工廠模式提供一個接口,用于創建相關或依賴對象的家族,而不需要明確指定具體類。

// 產品A接口
interface ProductA {void operationA();
}// 產品B接口
interface ProductB {void operationB();
}// 具體產品A1
class ConcreteProductA1 implements ProductA {@Overridepublic void operationA() {System.out.println("ConcreteProductA1 operationA");}
}// 具體產品A2
class ConcreteProductA2 implements ProductA {@Overridepublic void operationA() {System.out.println("ConcreteProductA2 operationA");}
}// 具體產品B1
class ConcreteProductB1 implements ProductB {@Overridepublic void operationB() {System.out.println("ConcreteProductB1 operationB");}
}// 具體產品B2
class ConcreteProductB2 implements ProductB {@Overridepublic void operationB() {System.out.println("ConcreteProductB2 operationB");}
}// 抽象工廠接口
interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}// 具體工廠1
class ConcreteFactory1 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA1();}@Overridepublic ProductB createProductB() {return new ConcreteProductB1();}
}// 具體工廠2
class ConcreteFactory2 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA2();}@Overridepublic ProductB createProductB() {return new ConcreteProductB2();}
}// 客戶端代碼
public class Client {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();ProductA productA1 = factory1.createProductA();ProductB productB1 = factory1.createProductB();productA1.operationA();productB1.operationB();AbstractFactory factory2 = new ConcreteFactory2();ProductA productA2 = factory2.createProductA();ProductB productB2 = factory2.createProductB();productA2.operationA();productB2.operationB();}
}

1.4 工廠模式的優缺點

優點:

  • 封裝了對象的創建過程,客戶端無需了解具體產品類
  • 可以輕松添加新產品而不影響現有代碼
  • 遵循開閉原則

缺點:

  • 引入了額外的類和接口,增加了系統復雜度
  • 在某些情況下可能會增加系統的抽象程度和理解難度

1.5 適用場景

  • 當一個類不知道它所需要創建的對象的類時
  • 當一個類希望由子類來指定它所創建的對象時
  • 當創建對象的過程涉及到復雜的業務邏輯時

二、單例模式

單例模式確保一個類只有一個實例,并提供一個全局訪問點。

2.1 餓漢式單例

public class EagerSingleton {// 在類加載時就創建實例private static final EagerSingleton INSTANCE = new EagerSingleton();// 私有構造函數,防止外部實例化private EagerSingleton() {// 防止通過反射創建多個實例if (INSTANCE != null) {throw new IllegalStateException("Singleton already initialized");}}// 提供全局訪問點public static EagerSingleton getInstance() {return INSTANCE;}// 示例方法public void doSomething() {System.out.println("Singleton is doing something");}
}

2.2 懶漢式單例(線程安全)

public class LazySingleton {// 初始不創建實例private static volatile LazySingleton instance;// 私有構造函數private LazySingleton() {// 防止通過反射創建多個實例if (instance != null) {throw new IllegalStateException("Singleton already initialized");}}// 提供全局訪問點,使用雙重檢查鎖定public static LazySingleton getInstance() {if (instance == null) {synchronized (LazySingleton.class) {if (instance == null) {instance = new LazySingleton();}}}return instance;}// 示例方法public void doSomething() {System.out.println("Singleton is doing something");}
}

2.3 枚舉實現單例

public enum EnumSingleton {INSTANCE;// 示例方法public void doSomething() {System.out.println("Enum Singleton is doing something");}
}// 使用方式
public class Client {public static void main(String[] args) {EnumSingleton.INSTANCE.doSomething();}
}

2.4 靜態內部類實現單例

public class StaticInnerSingleton {// 私有構造函數private StaticInnerSingleton() {}// 靜態內部類持有單例實例private static class SingletonHolder {private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();}// 提供全局訪問點public static StaticInnerSingleton getInstance() {return SingletonHolder.INSTANCE;}// 示例方法public void doSomething() {System.out.println("Static inner class Singleton is doing something");}
}

2.5 單例模式的優缺點

優點:

  • 保證一個類只有一個實例,減少內存開銷
  • 提供全局訪問點,便于全局控制
  • 實例只創建一次,避免多次實例化的性能開銷

缺點:

  • 不適用于變化頻繁的對象
  • 單例模式的擴展有一定難度
  • 單例可能導致單一職責原則的違反

2.6 適用場景

  • 需要頻繁創建和銷毀的對象
  • 創建對象時耗時過多或耗費資源過多的對象
  • 工具類對象
  • 頻繁訪問數據庫或文件的對象

總結

本文詳細介紹了兩種種常用的創建型設計模式:工廠模式、單例模式和建造者模式。它們各自有不同的應用場景:

  • 工廠模式:當需要將對象的創建與使用分離,或者需要創建一系列相關對象時使用。
  • 單例模式:當系統中需要保證一個類只有一個實例,并提供全局訪問點時使用。

這些設計模式都是面向對象設計的重要工具,理解并正確應用它們可以幫助我們編寫出更加靈活、可維護的代碼。

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

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

相關文章

Jenkins 2.426.2配置“構建歷史的顯示名稱,加上包名等信息“

Jenkins 2.426.2配置“構建歷史的顯示名稱,加上包名等信息" 需求:想要在構建歷史中展示,本次運行的是哪個版本或哪個包 操作步驟: 1、先安裝插件Build Name and Description Setter 2、Set Build Name 3、構建歷史處查看展示 插件特性說明 安裝依賴:需手動安裝 Build …

為何在VMware中清理CentOS虛擬機后,本地磁盤空間未減少的問題解決

文章目錄 前言原因:虛擬機磁盤,到底是咋回事?為啥空間沒變小? 解決方案 前言 在使用VMware運行CentOS虛擬機時,你是否曾遇到過這樣的情況:明明在虛擬機內刪除了大量文件,rm -rf 后發現并沒什么用&#xff…

Development靶機通關筆記

一、主機發現 arp-scan -l靶機ip為192.168.55.152 二、端口掃描、目錄枚舉、漏洞掃描、指紋識別 2.1端口掃描 nmap --min-rate 10000 -p- 192.168.55.152發現靶機沒有開放80端口,開放的是8080端口 UDP端口掃描 nmap -sU --min-rate 10000 -p- 192.168.55.152靶…

自然語言處理核心技術:詞向量(Word Embedding)解析

自然語言處理核心技術:詞向量(Word Embedding)全面解析 在自然語言處理(NLP)領域,如何讓計算機理解人類語言的語義一直是核心挑戰。詞向量(Word Vector),又稱詞嵌入&…

【Matlab】雷達圖/蛛網圖

文章目錄 一、簡介二、安裝三、示例四、所有參數說明 一、簡介 雷達圖(Radar Chart)又稱蛛網圖(Spider Chart)是一種常見的多維數據可視化手段,能夠直觀地對比多個指標并揭示其整體分布特征。 雷達圖以中心點為原點&…

Vue3實現輪播表(表格滾動)

在這之前,寫過一篇Vue2實現該效果的博文:vue-seamless-scroll(一個簡單的基于vue.js的無縫滾動) 有興趣也可以去看下,這篇是用vue3實現,其實很簡單,目的是方便后面用到直接復制既可以了。 安裝: <

安卓開發用到的設計模式(1)創建型模式

安卓開發用到的設計模式&#xff08;1&#xff09;創建型模式 文章目錄 安卓開發用到的設計模式&#xff08;1&#xff09;創建型模式1. 單例模式&#xff08;Singleton Pattern&#xff09;2. 工廠模式&#xff08;Factory Pattern&#xff09;3. 抽象工廠模式&#xff08;Abs…

后端開發概念

1. 后端開發概念解析 1.1. 什么是服務器&#xff0c;后端服務 1.1.1. 服務器 服務器是一種提供服務的計算機系統&#xff0c;它可以接收、處理和響應來自其他計算機系統&#xff08;客戶端&#xff09;的請求。服務器主要用于存儲、處理和傳輸數據&#xff0c;以便客戶端可以…

Spring AI 源碼解析:Tool Calling鏈路調用流程及示例

Tool工具允許模型與一組API或工具進行交互&#xff0c;增強模型功能&#xff0c;主要用于&#xff1a; 信息檢索&#xff1a;從外部數據源檢索信息&#xff0c;如數據庫、Web服務、文件系統或Web搜索引擎等 采取行動&#xff1a;可用于在軟件系統中執行特定操作&#xff0c;如…

Spyglass:跨時鐘域同步(長延遲信號)

相關閱讀 Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828934.html?spm1001.2014.3001.5482 簡介 長延遲信號方案用于控制或數據信號跨時鐘域同步&#xff0c;該方案將使用quasi_static約束的跨時鐘域信號視為已同步&#xff0c;如圖1所示。 // test.sgdc q…

Linux云計算訓練營筆記day13【CentOS 7 find、vim、vimdiff、ping、wget、curl、RPM、YUM】

Linux云計算訓練營筆記day13[CentOS 7 find、vim、vimdiff、ping、wget、curl、RPM、YUM]] 目錄 Linux云計算訓練營筆記day13[CentOS 7 find、vim、vimdiff、ping、wget、curl、RPM、YUM]]1.find練習2.vim高級使用2.1 命令模式:2.2 插入模式:2.3 末行模式: 3. vimdiff4. ping5.…

網絡流量分析工具ntopng的安裝與基本使用

網絡流量分析工具ntopng的安裝與基本使用 一、ntopng基本介紹1.1 ntopng簡介1.2 主要特點1.3 使用場景 二、本地環境介紹2.1 本地環境規劃2.2 本次實踐介紹 三、安裝ntopng工具3.1 官網地址3.2 配置軟件源3.3 添加軟件源3.4 安裝ntopng 四、ntopng的基本配置4.1 修改配置文件4.…

數據的獲取與讀取篇---常見的數據格式JSON

文件格式 假如你有一份想分析的數據文件,獲得文件后下一步就是用代碼讀取它。不同的文件格式有不同的讀取方法。所以讀取前了解文件格式也很重要。你可能見過非常多的文件格式,例如TXT、MP3、PDF、JPEG等等。 一般可以通過文件的后綴來分辨文件的格式,例如TXT格式,一般保存…

人工智能發展

探秘人工智能領域的熱門編程語言與關鍵知識 在當今科技飛速發展的時代&#xff0c;人工智能已滲透到生活的各個角落&#xff0c;從智能語音助手到精準的推薦系統&#xff0c;從自動駕駛汽車到醫療影像診斷&#xff0c;人工智能正以前所未有的速度改變著世界。而在這背后&#x…

超全GPT-4o 風格提示詞案例,持續更新中,附使用方式

本文匯集了各類4o風格提示詞的精選案例&#xff0c;從基礎指令到復雜任務&#xff0c;從創意寫作到專業領域&#xff0c;為您提供全方位的參考和靈感。我們將持續更新這份案例集&#xff0c;確保您始終能夠獲取最新、最有效的提示詞技巧。 讓我們一起探索如何通過精心設計的提…

Vue3響應式數據: 深入分析Ref與Reactive

Vue3響應式數據: 深入分析Ref與Reactive 介紹 作為一個流行的前端框架&#xff0c;其響應式數據系統是其核心特性之一。在Vue3中&#xff0c;我們可以使用Ref和Reactive兩種方式來創建響應式數據。本文將深入分析Ref與Reactive&#xff0c;幫助讀者更好地理解Vue3的響應式數據系…

云計算,大數據,人工智能

1. 云計算&#xff1a;彈性資源與分布式計算 案例&#xff1a;基于AWS EC2的動態資源擴展 場景&#xff1a;電商網站在“雙十一”期間流量激增&#xff0c;需要臨時擴容服務器資源。 代碼&#xff1a;使用AWS Boto3庫動態啟動EC2實例 import boto3# 創建EC2客戶端 ec2 boto…

Linux(7)——進程(概念篇)

一、基本概念 書本上的概念&#xff1a;程序的一個執行實例&#xff0c;正在執行的程序等 基于內核的觀點&#xff1a;擔當分配系統資源(CPU時間&#xff0c;內存)的實體。 我們知道&#xff0c;我們在寫代碼的時候&#xff0c;你的代碼進行編譯鏈接后生成可執行文件&#xff…

【Harmony】【鴻蒙】List列表View如何刷新內部的自定義View的某一個控件

創建自定義View Component export struct TestView{State leftIcon?:Resource $r(app.media.leftIcon)State leftText?:Resource | string $r(app.string.leftText)State rightText?:Resource | string $r(app.string.rightText)State rightIcon?:Resource $r(app.med…

Docker安裝MySQL集群(主從復制)

為確保生產環境中的數據安全與可靠性&#xff0c;數據庫普遍采用主從集群架構&#xff08;一主一從&#xff09;進行部署。本文將系統闡述如何利用Docker鏡像實現數據庫集群的容器化部署&#xff0c;并完整記錄各配置環節的具體實現步驟。 一、主服務實例創建&#xff08;可以…