設計模式精講 Day 1:單例模式(Singleton Pattern)

【設計模式精講 Day 1】單例模式(Singleton Pattern)


文章內容

開篇

在軟件開發中,設計模式是解決常見問題的通用解決方案。作為“設計模式精講”系列的第一天,我們將深入講解單例模式(Singleton Pattern),這是創建型模式中最基礎、最常用的一種。

單例模式的核心思想是:確保一個類只有一個實例,并提供一個全局訪問點。它廣泛應用于需要共享資源、控制資源訪問或保證唯一性的場景,如數據庫連接池、配置管理器、日志系統等。

本文將從理論到實踐,全面解析單例模式的設計原理、實現方式、應用場景以及在Java中的實際應用,幫助你掌握這一經典設計模式,并在項目中靈活運用。


模式定義

單例模式是一種創建型設計模式,它確保一個類在整個應用程序中只存在一個實例,并提供一個全局訪問該實例的方法。

其核心思想是:

  • 限制類的實例化次數,僅允許創建一次。
  • 提供一個全局訪問點,方便其他對象獲取該實例。

模式結構

單例模式的UML類圖包含以下關鍵角色:

角色說明
Singleton單例類,負責控制實例的創建和訪問

在代碼中,Singleton 類通常包含以下元素:

  • 一個私有構造函數,防止外部直接實例化。
  • 一個靜態的私有實例變量,用于保存唯一的實例。
  • 一個公共的靜態方法(如 getInstance()),用于返回該實例。

適用場景

單例模式適用于以下典型場景:

場景描述
全局配置管理如應用的配置信息,只需加載一次
數據庫連接池確保多個組件共享同一個數據庫連接池
日志記錄器保證所有模塊使用同一個日志輸出
緩存管理控制緩存數據的唯一性
資源管理器如線程池、網絡連接等資源的統一管理

實現方式

下面是一個完整的Java實現示例,展示了單例模式的多種實現方式:

餓漢式單例(線程安全)

/*** 餓漢式單例:類加載時就初始化實例,線程安全*/
public class Singleton {// 私有靜態實例,類加載時就初始化private static final Singleton instance = new Singleton();// 私有構造函數,防止外部實例化private Singleton() {}// 公共靜態方法,返回唯一實例public static Singleton getInstance() {return instance;}// 示例方法public void showMessage() {System.out.println("This is a singleton instance.");}
}

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

/*** 懶漢式單例:延遲初始化,但不保證線程安全*/
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}public void showMessage() {System.out.println("Lazy singleton instance.");}
}

雙重檢查鎖(DCL)單例(線程安全)

/*** DCL(雙重檢查鎖)單例:線程安全且延遲初始化*/
public class DCLSingleton {private static volatile DCLSingleton instance;private DCLSingleton() {}public static DCLSingleton getInstance() {if (instance == null) {  // 第一次檢查synchronized (DCLSingleton.class) {if (instance == null) {  // 第二次檢查instance = new DCLSingleton();}}}return instance;}public void showMessage() {System.out.println("DCL singleton instance.");}
}

枚舉單例(推薦方式)

/*** 枚舉單例:線程安全、防止反射攻擊、序列化安全*/
public enum EnumSingleton {INSTANCE;public void showMessage() {System.out.println("Enum singleton instance.");}
}

工作原理

單例模式通過以下機制實現:

  1. 限制構造函數訪問:通過將構造函數設為私有,防止外部通過 new 創建實例。
  2. 靜態實例變量:使用靜態變量存儲唯一實例,確保整個應用中只有一個實例。
  3. 靜態訪問方法:通過靜態方法 getInstance() 提供對實例的訪問,避免直接暴露構造函數。

在多線程環境下,需特別注意線程安全問題。例如,懶漢式單例未加鎖會導致多個線程同時創建實例,而使用 volatile 和雙重檢查鎖可以有效避免此問題。


優缺點分析

優點缺點
確保全局唯一性,便于資源共享過度使用可能導致耦合,難以測試
提高性能,減少資源開銷不適合需要頻繁創建和銷毀的對象
易于維護和擴展不適合需要動態實例化的場景

案例分析:日志系統

在實際項目中,日志系統常使用單例模式來確保所有模塊都使用同一個日志實例。

問題描述

在一個大型系統中,多個模塊都需要記錄日志,如果每個模塊都獨立創建日志對象,會導致資源浪費和日志信息不一致。

解決方案

使用單例模式創建一個全局的日志記錄器,所有模塊通過該實例進行日志操作。

/*** 日志記錄器,使用單例模式*/
public class Logger {private static volatile Logger instance;private Logger() {}public static Logger getInstance() {if (instance == null) {synchronized (Logger.class) {if (instance == null) {instance = new Logger();}}}return instance;}public void log(String message) {System.out.println("[LOG] " + message);}
}// 使用示例
public class App {public static void main(String[] args) {Logger logger = Logger.getInstance();logger.log("Application started.");}
}

與其他模式的關系

單例模式與以下設計模式有密切關系:

模式關系說明
工廠模式工廠模式可以創建單例對象,但單例模式更關注唯一性
抽象工廠抽象工廠通常返回一組相關對象,而單例模式專注于單一對象
代理模式代理模式可以包裝單例對象,增加額外功能
原型模式原型模式通過復制創建對象,而單例模式強調唯一性

總結

今天我們詳細講解了單例模式,包括它的定義、結構、適用場景、多種實現方式、工作原理、優缺點、真實案例以及與其他模式的關系。

通過本篇文章,你應該已經掌握了:

  • 單例模式的核心思想;
  • Java中不同實現方式的優劣;
  • 如何在實際項目中使用單例模式;
  • 單例模式在Java標準庫和框架中的應用。

下一天,我們將進入“設計模式精講”的第二天,講解工廠方法模式(Factory Method Pattern),敬請期待!


標簽

設計模式, 單例模式, Java, 設計模式精講, 軟件架構, 編程技術, 面向對象設計, Java設計模式


文章簡述

本文是“設計模式精講”系列的第一篇,深入講解了單例模式(Singleton Pattern)。文章從理論出發,結合Java代碼示例,詳細闡述了單例模式的核心思想、實現方式、適用場景及優缺點。通過真實項目案例(如日志系統),展示了如何在實際開發中應用該模式。同時,文章還對比了單例模式與其他設計模式的關系,并探討了其在Java標準庫中的應用。本文旨在幫助開發者理解并掌握單例模式,提升代碼質量和可維護性,為后續設計模式的學習打下堅實基礎。


進一步學習資料

  1. 《設計模式:可復用面向對象軟件的基礎》 —— GoF 經典著作
  2. Java Design Patterns - Oracle Docs
  3. Design Patterns in Java - Baeldung
  4. Singleton Pattern - Refactoring Guru
  5. Java并發編程實戰 - 《Java Concurrency in Practice》

核心設計思想總結

通過本文的學習,我們掌握了單例模式的核心思想:確保一個類只有一個實例,并提供全局訪問點。該模式在資源管理、配置中心、日志系統等場景中具有重要價值。

在實際項目中,合理使用單例模式可以提高系統性能、降低資源消耗、增強代碼可維護性。然而,也應注意避免濫用,特別是在需要頻繁創建和銷毀對象的場景中。

希望你在今后的開發中能夠靈活運用單例模式,寫出更加優雅、高效的代碼。

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

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

相關文章

【衛星通信】3GPP標準提案:面向NB-IoT(GEO)場景的IMS信令優化方案-降低衛星通信場景下的語音呼叫建立時延

一、引言 隨著5G非地面網絡(NTN)技術的演進,基于NB-IoT的衛星通信(如GEO地球同步軌道衛星)逐漸成為偏遠地區語音服務的重要補充。然而,傳統IP多媒體子系統(IMS)的信令流程在帶寬受限…

軟件測試之簡單基礎的安全測試方法(另外包含軟測面試題庫)

文章目錄 前言安全測試是什么簡單基礎的安全測試方法密碼安全操作權限驗證SQL注入xss腳本攻擊文件上傳下載安全漏洞掃描Web掃描APP掃描 面試題庫(僅參考)參考目錄 前言 閱讀本文前請注意最后編輯時間,文章內容可能與目前最新的技術發展情況相…

LCEL:LangChain 表達式語言詳解與測試工程師的實踐指南

引言 在 AI 應用開發中,如何高效地組合多個步驟(如提示模板、模型調用、輸出解析)并優化執行流程,是開發者和測試工程師共同面臨的挑戰。LangChain Expression Language (LCEL) 作為 LangChain 的核心功能之一,提供了…

LeetCode面試經典150題—旋轉數組—LeetCode189

原題請見:Leetcode189-旋轉數組 1、題目描述 2、題目分析 首先容易想到的最簡單的方案,是算出來移動K步之后,新數組的每一個坐標與原坐標的映射關系,然后根據映射關系放到一個全新的數組,再把新數組的值賦給原數組。…

2.5 Rviz使用教程

新建終端,鍵入命令 roslaunch wpr_simulation wpb_simple.launch 再新建終端,鍵入命令 rviz修改Fix Frame 為 base_footprint 點擊add之后選擇RobotModel 再增加一個LaserScan 選擇激光雷達話題 可視化效果 配置的兩種方法 1.在Gazebo運行的基礎上&…

基于SpringBoot+JSP開發的招投標采購信息平臺

角色: 管理員、普通用戶 技術: 后端:Spring Boot Mybatis-Plus MySQL 前端:JSP 核心功能: 該平臺是一個用于管理投標和招標信息的系統,主要提供信息發布、用戶管理和交易管理等核心功能。 功能介紹…

【項目實訓#10】HarmonyOS API文檔RAG檢索系統后端實現

【項目實訓#10】HarmonyOS API文檔RAG檢索系統后端實現 文章目錄 【項目實訓#10】HarmonyOS API文檔RAG檢索系統后端實現一、背景簡介二、RAG技術原理與架構設計2.1 RAG技術原理回顧與提升2.2 系統架構設計 三、RAG引擎核心實現3.1 RAG引擎初始化3.2 查詢向量化3.3 文檔檢索實現…

專注于PLC數據采集MES交互解決方案

專注于PLC數據采集MES交互解決方案 前篇文章我們講到當下的制造行業在工業4.0的大趨勢下,MES系統成為現場制造過程管制的有利武器,更是質量追蹤的一把好工具。我們要知道產品在各個加工環節的結果。除了人工在各個制造環節錄入制造結果外,更…

微信小程序實現文字逐行動畫效果渲染顯示

1. 微信小程序實現文字逐行動畫效果渲染顯示 在微信小程序開發中,為了文字逐行動畫效果渲染可以通過JavaScript 和 WXML 的動態數據綁定來實現,實現文字逐行顯示的效果,同時結合 CSS 動畫提升視覺體驗。 ??如果需要更復雜的動畫效果(如縮放、移動等),可以使用微信小程序…

Redux 原理深度剖析

1. Redux 實現 定義 Action 和 Reducer 類型,為了簡便,先用JavaScript來演示。 1.1. 定義Action和Reducer類型 // 定義 Action 類型 /*** typedef {Object} Action* property {string} type*/// 定義 Reducer 類型 /*** callback Reducer* param {any…

【LangChain】4 基于文檔的問答

對于給定的文檔, 比如從PDF、網頁、公司主頁中提取構建的內部文檔集合,我們可以使用大語言模型來回答關于這些文檔內容的問題,以幫助用戶更有效地獲取和使用他們所需要的信息。這種方式非常有效且靈活地適用于實際應用場景,因為它不僅僅利用大…

基于Netty的TCP Server端和Client端解決正向隔離網閘數據透傳問題

背景 因為安裝了正向隔離網閘&#xff0c;導致數據傳輸的時候僅支持TCP協議和UDP協議&#xff0c;因此需要開發TCP Client和Server服務來將數據透傳&#xff0c;當前環境是獲取的數據并將數據轉發到kafka 1.引入依賴 <dependency><groupId>io.netty</groupId>…

Cursor鏈接遠程服務器實現項目部署

想獲取更多高質量的Java技術文章&#xff1f;歡迎訪問Java技術小館官網&#xff0c;持續更新優質內容&#xff0c;助力技術成長 技術小館官網 在軟件開發過程中&#xff0c;遠程服務器開發是一種常見的工作模式。通過遠程連接服務器進行代碼編寫和環境配置&#xff0c;可以充分…

Redis集群模式之Redis Cluster(3)

上篇文章我們講解了Redis Cluster的狀態監測與恢復過程&#xff0c;這篇文章我們來進行Redis Cluster內容的收尾&#xff0c;將其擴容和縮容的過程進行講解&#xff0c;并分析RedisCluster的優缺點。 擴容和縮容 當集群中出現容量限制或者其他一些原因需要擴容時&#xff0c;R…

Cursor ReAct Agent技術架構

一、架構核心思想 “零熵操作交給AI”理念 Cursor通過ReAct模式實現編程中重復性工作的自動化&#xff1a; 零熵操作&#xff1a;機械性任務&#xff08;代碼補全/格式化/重構/語法修復/導入管理&#xff09; Tab-away機制&#xff1a;一鍵接受AI建議&#xff0c;保持思維連續…

國學IP行業實戰洞察:聚焦創客匠人,解鎖創始人IP與知識變現新路徑

國學行業正經歷“文化價值”與“商業變現”的深度融合&#xff0c;2023年市場規模突破千億大關&#xff0c;年增速超 10%。在“IP化數字化”浪潮中&#xff0c;創客匠人作為垂直領域技術服務商&#xff0c;以全鏈路工具矩陣為支點&#xff0c;撬動國學創始人IP從內容生產到商業…

R語言開發入門完整指南

R語言開發入門完整指南 目錄 R語言簡介環境配置包管理基本語法數據類型和結構數據操作統計分析數據可視化編程結構實用技巧學習資源 R語言簡介 R是一種專為統計計算和圖形設計的編程語言&#xff0c;廣泛應用于數據分析、統計建模、機器學習和數據可視化。R語言具有以下特點…

ObservedV2裝飾器和Trace裝飾器

為了對嵌套類對象屬性變化直接觀測&#xff0c;華為提供了ObservedV2和Trace裝飾器。這兩個裝飾器必須搭配使用&#xff0c;單獨使用任何一個都不會起任何作用&#xff1b;在繼承類中也可監測&#xff1b;ObservedV2的類實例目前不支持使用JSON.stringify進行序列化&#xff0c…

6月計算機新書:深度學習、大模型、DeepSeek

六月&#xff0c;這個充滿活力與希望的季節&#xff0c;三本重磅新書《深度學習&#xff1a;基礎與概念》、《MCP極簡開發&#xff1a;輕松打造高效智能體》與《大模型應用開發&#xff1a;RAG實戰課》翩然而至&#xff0c;為我們開啟了一場探索科技前沿的奇妙之旅。一起來看詳…

扁平風格職場商務通用PPT模版分享

扁平風格PPT模版&#xff0c;創意卡通扁平化通用PPT模版&#xff0c;創意扁平化勵志論文答辯PPT模版&#xff0c;卡通職場商務PPT模版&#xff0c;職場培訓&#xff0c;項目策劃&#xff0c;工作總結類PPT模版&#xff0c;互聯網電子商務PPT模版 扁平風格職場商務通用PPT模版分…