很多 Java 初學者覺得設計模式 “抽象難學”,其實是沒抓住核心邏輯 —— 設計模式不是 “炫技代碼”,而是前輩們總結的 “解決高頻復雜問題的通用思路”,好吧,你可以過一遍了解這些大概是個什么東西
不求我們能夠完全理解,畢竟我們小時候家人跟我們說人生大道理我們也不太當回事
一、先明確:Java 設計模式到底是什么?
一句話總結核心:設計模式是 “針對 Java 開發中重復出現的復雜場景,前輩們總結的、可復用的代碼解決思路”。
你可以從 3 個角度理解,瞬間消除 “抽象感”:
- 不是 “固定代碼模板”,而是 “解決問題的思路”
比如 “單例模式” 的核心思路是 “讓一個類只創建一個對象”,具體代碼可以有
“雙重檢查鎖”“靜態內部類” 等多種寫法,但 “只存一個實例” 的思路不變。
生活類比:“做米飯要先加水再加熱” 是思路,具體用電飯鍋還是高壓鍋,是實現方式 —— 思路統一,實現靈活。
-
只解決 “特定復雜問題”,不是 “萬能工具”
設計模式針對的是 “不用就會踩坑” 的場景:比如 “想避免重復創建對象浪費資源”“想動態切換支付方式又不想寫一堆 if-else”“想加日志又不改動原有業務代碼”。
簡單場景(比如一個工具類只提供 1 個靜態方法)不需要設計模式,直接寫簡單代碼更高效。 -
核心價值是 “讓代碼易維護、易擴展”
沒有設計模式的代碼,后期迭代會變成 “一團亂麻”:比如新增支付方式要改原有代碼、加日志要在每個方法里寫重復邏輯。
設計模式能讓代碼 “解耦”—— 新增功能不用改老代碼、增強邏輯不侵入業務,后期維護不用 “牽一發而動全身”。
二、Java 開發中最常用的設計模式有哪些?
設計模式官方有 23 種,但 Java 開發者日常用得最多、面試問得最頻繁的,集中在3 大類 8 種,按 “解決的核心問題” 分類,一目了然:
三、創建型模式
1. 單例模式(Singleton)—— 一個類只創建一個對象
- 定義
保證一個類在整個 Java 程序運行過程中,只有一個實例對象
,并且提供一個全局統一的訪問入口。 - 生活例子
公司的 “CEO”—— 全公司只有 1 位 CEO,所有部門對接 CEO 時,都只能找這同一個人,不可能同時存在兩位 CEO;而且所有人都知道 “找 CEO 要通過秘書(全局入口)”,不能自己 “造一個 CEO”。 - 業務場景 :
日志工具類 :日志需要統一寫入文件 / 數據庫,多實例會導致日志內容錯亂;
線程池: 線程池需要控制線程數量,多實例會導致線程過多,耗盡服務器資源;
數據庫連接池:數據庫連接數有限,多實例會導致連接超標,數據庫拒絕訪問。
2. 簡單工廠模式(Simple Factory)—— 統一創建同一類對象
- 定義
定義一個 “工廠類”,由工廠統一創建同一類別下的所有對象(比如各種支付方式、各種日志類型),外部不用關心對象的創建細節,只需要告訴工廠
“要什么”,就能拿到對應的對象。 - 生活例子
奶茶店的 “收銀臺”—— 顧客不用自己動手做奶茶(不用關心奶茶怎么煮、怎么加配料),只需要告訴收銀臺(工廠)“要珍珠奶茶” 或
“要水果茶”,收銀臺就會給顧客對應的奶茶(產品)。 - 業務場景
支付系統:需要創建微信支付、支付寶支付、銀聯支付對象,用工廠根據用戶選擇的支付方式統一創建;
日志系統:需要創建文件日志、控制臺日志、數據庫日志對象,用工廠根據配置統一創建;
文檔導出:需要創建 Excel 導出、PDF 導出、Word 導出對象,用工廠根據用戶選擇的格式統一創建。
3. 建造者模式(Builder)—— 分步創建復雜對象
- 定義
針對 “有多個屬性(尤其是可選屬性)的復雜對象”,將對象的創建過程拆分成多個步驟,逐步設置屬性,最后統一構建出完整對象,避免創建出
“屬性不完整” 的對象。 - 生活例子
組裝電腦 —— 電腦有 “CPU、內存、硬盤” 等必選屬性(沒有這些電腦無法運行),還有 “顯卡、鍵盤、鼠標” 等可選屬性(沒有也能運行,但體驗差)。組裝時,必須先裝必選部件,再按需裝可選部件,最后拼成完整電腦。 - 業務場景
訂單創建:訂單有 “訂單號、商品 ID、金額” 等必選屬性,有 “收貨地址、優惠券、備注” 等可選屬性;
用戶注冊:用戶有 “手機號、密碼” 等必選屬性,有 “昵稱、頭像、生日” 等可選屬性;
文檔生成:文檔有 “標題、內容” 等必選屬性,有 “作者、日期、封面” 等可選屬性。
四、結構型模式
1. 代理模式(Proxy)—— 給對象加 “增強層”
- 定義
給 “目標對象”(核心業務對象)創建一個 “代理對象”,外部通過代理對象訪問目標對象,在訪問前后可以添加額外邏輯(比如日志、權限、事務),不修改目標對象的代碼。 - 生活例子
明星的 “經紀人”—— 粉絲想找明星商演(訪問目標對象),不能直接聯系明星,必須通過經紀人(代理對象):經紀人會先 “篩選商演需求”(權限校驗)、“記錄行程”(日志),再安排明星去商演(調用目標對象方法),商演后還會 “結算費用”(后續增強)。 - 業務場景
Spring AOP:給 Service 方法加事務(代理在方法前開啟事務,方法后提交 / 回滾);
日志記錄:給 Controller 方法加訪問日志(代理在方法前記錄請求參數,方法后記錄返回結果);
權限校驗:給敏感接口加權限(代理在方法前判斷用戶是否有權限,無權限則拒絕)。
2. 策略模式(Strategy)—— 動態切換邏輯,消除 if-else
- 定義
將 “不同的算法 / 邏輯” 封裝成獨立的“策略類”
,策略類
之間可以互相替換,外部根據場景動態選擇對應的策略,不用在代碼中寫大量 if-else。 - 生活例子
出行方式選擇 —— 去公司可以選 “地鐵”“公交”“打車” 三種策略:趕時間選 “打車”,想省錢選 “公交”,平衡時間和成本選 “地鐵”。每種策略的 “路線、費用、時間” 獨立,且可以隨時切換。 - 業務場景
訂單折扣:普通用戶無折扣、會員 9 折、VIP8 折,根據用戶等級動態選策略;**
支付方式 :微信、支付寶、銀聯支付,根據用戶選擇動態選策略;
排序算法:數據量小用 “冒泡排序”,數據量大用 “快速排序”,根據數據量動態選策略。
3. 裝飾器模式(Decorator)—— 動態給對象加功能
- 定義
在不修改原有對象代碼的前提下,通過 “包裝” 的方式給對象動態添加新功能,并且可以靈活組合多個功能(比繼承更靈活)。 - 生活例子
咖啡店的 “咖啡加配料”—— 一杯美式咖啡(基礎對象)可以加奶泡(裝飾器 1)、加糖(裝飾器 2)、加冰(裝飾器 3),每種配料都是一個獨立的 “裝飾”,可以自由組合(比如 “美式 + 奶泡 + 糖”“美式 + 冰”),且不改變咖啡本身的制作邏輯。 - 業務場景
日志增強:基礎日志功能可以動態添加 “時間戳裝飾”“用戶 ID 裝飾”“模塊名稱裝飾”;
數據加密:基礎數據傳輸可以動態添加“Base64 加密裝飾”
,“MD5 加密裝飾”
;
IO 流擴展:Java 中的BufferedInputStream
就是FileInputStream
的裝飾器,添加了緩沖功能。
五、行為型模式
1. 適配器模式(Adapter)—— 讓不兼容的類一起工作
- 定義
將一個類的接口轉換成客戶端期望的另一個接口,使原本因接口不兼容而無法一起工作的類能夠協同工作。 - 生活例子
手機充電器 “轉接頭”—— 安卓手機充電器(原有接口)不能直接給蘋果手機(目標接口)充電,用一個轉接頭(適配器)就能讓安卓充電器給蘋果手機充電,轉接頭內部完成 “安卓接口” 到 “蘋果接口” 的轉換。 - 業務場景
老系統升級:老系統返回 XML 格式數據,新系統需要 JSON 格式,用適配器轉換;
第三方接口集成:第三方接口返回的字段名(如user_name
)和本地系統(如username
)不一致,用適配器映射;
舊 API 兼容:項目中原來的Payment接口有pay(double amount)方法,新引入的支付 SDK 方法是doPayment(BigDecimal money),用適配器適配。
2. 觀察者模式(Observer)—— 實現對象間的動態通知
- 定義
當一個對象(被觀察者)的狀態發生變化時,所有依賴它的對象(觀察者)會自動收到通知并更新,實現 “一對多” 的動態通信。 - 生活例子
微信公眾號 —— 你關注的公眾號(被觀察者)發布新文章時,所有關注該公眾號的用戶(觀察者)都會收到推送通知,用戶可以選擇閱讀或忽略,但公眾號不需要知道具體有哪些用戶關注它。 - 業務場景
電商庫存預警:商品庫存低于閾值時,自動通知 “庫存管理系統”“訂單取消系統”“用戶提醒系統”;
消息隊列:生產者發送消息到隊列(被觀察者),所有訂閱該隊列的消費者(觀察者)自動接收消息;
GUI 事件處理:按鈕(被觀察者)被點擊時,所有注冊了點擊事件的監聽器(觀察者)自動執行回調。
總結:8 種常用設計模式的核心價值?
這 8 種設計模式覆蓋了 Java 開發中 “創建對象、組織結構、協調行為” 的核心場景,記住它們的核心解決點:
實際開發中,不必刻意追求 “用了多少模式”,而是當遇到對應痛點時,能想到 “用哪種模式可以更優雅地解決”—— 這才是學設計模式的最終目的。