設計模式是軟件開發的「內功心法」,GoF《設計模式》一書定義的 23 種經典模式常讓初學者望而生畏。本文嘗試用程序員熟悉的「追妹子 (MM)」生活場景,將每個模式的核心意圖、結構、適用場景一一映射,**僅作記憶輔助,嚴禁作為架構決策依據**。理解精髓,靈活組合,才是模式學習的正道。
| 模式 | 生活場景 | 核心意圖 | 關鍵點 |
|---|---|---|---|
| Simple Factory 簡單工廠 | 去麥當勞/肯德基點雞翅,只說「來四個雞翅」,不管哪家廚房做 | 客戶與具體產品解耦,工廠類集中創建邏輯 | 工廠類集中 if-else,違反開閉原則,適合產品固定少變場景 |
| Factory Method 工廠方法 | 帶 MM 吃漢堡,自己不決定吃什麼,讓 MM 直接跟服務員點 | 定義創建接口,子類決定實例化哪個具體類 | 核心工廠不再負責具體創建,擴展新產品只需加子類 |
| Abstract Factory 抽象工廠 | 買套裝:上衣+褲子+鞋,必須同品牌同風格(運動/正裝/休閒) | 創建相關/依賴對象族,無需指定具體類 | 產品族內部約束強,增加新產品族易,增加新產品等級難 |
| Builder 建造者 | 多語言「我愛你」翻譯機,按鍵選語言,組裝出完整表白句子 | 將複雜對象構建與表示分離,分步構建可生成不同表示 | 構建過程穩定,部件靈活變化;Director 指揮 Builder 步驟 |
| Prototype 原型 | 收集 100 句肉麻情話,需要時直接 Copy-Paste 發給 MM | 通過複製原型實例創建新對象,避免 new 開銷或構建複雜 | 需實現 Cloneable,區分淺/深複製;適用於類實例化成本高場景 |
| Singleton 單例 | 6 個老婆共用 1 個老公(我),喊「老公」指向同一人 | 保證類全局唯一實例,並提供全局訪問點 | 私有構造器 + 靜態工廠方法;雙重檢查鎖/靜態內部類/枚舉實現線程安全 |
| 模式 | 生活場景 | 核心意圖 | 關鍵點 |
|---|---|---|---|
| Adapter 適配器 | 不懂粵語的我,靠懂雙語的 Kent 與港妹 Sarah 溝通 | 將一個類接口轉換為客戶期望的另一接口,使不兼容類協同工作 | 類適配器(繼承) vs 對象適配器(組合);雙向適配器更靈活 |
| Bridge 橋接 | 早安/晚安 × 讚美衣服/讚美髮型 = 4 種組合,獨立變化不爆炸 | 將抽象與實現解耦,使二者可獨立變化(組合替代繼承) | 抽象持有實現引用;適用於多維度變化、避免類爆炸 |
| Composite 組合 | MM 生日買 T恤+裙子+包包,說「這是一套禮物」,實則三件 | 將對象組合成樹結構表示「部分-整體」層次,客戶統一對待單個/組合 | Component 定義公共接口,Leaf/Composite 實現;遞歸遍歷 |
| Decorator 裝飾器 | 照片 → 寫情話 → 裝相框 → 包裝盒,層層包裝,核心還是「我」 | 動態給對象添加職責,比繼承更靈活;可疊加多層裝飾 | 裝飾器持有被裝飾對象引用,實現同接口;Java I/O 流經典應用 |
| Facade 外觀 | 專業相機有「自動檔」,MM 只需按快門,光圈快門 ISO 全自動 | 為子系統提供統一高層接口,降低客戶使用複雜度 | 不限制客戶直接訪問子系統;通常單例;Spring ApplicationContext 即外觀 |
| Flyweight 享元 | 手機存常用語「吃了嗎/睡了嗎」,發短信時加上 MM 名字發送 | 共享細粒度對象,區分內部狀態(共享)與外部狀態(參數傳入) | 工廠管理享元池;String 池、Integer 緩存、線程池均為享元思想 |
| Proxy 代理 | 聊天機器人自動回覆「嗨/幾歲/身高」,只把非標準問題轉給我 | 為對象提供代理控制訪問,可延遲加載、權限控制、日誌、遠程調用 | 靜態代理/動態代理(JDK/CGLIB);Spring AOP 底層即動態代理 |
| 模式 | 生活場景 | 核心意圖 | 關鍵點 |
|---|---|---|---|
| Chain of Responsibility 責任鏈 | 傳紙條「願意做女友請保留,不願意向前傳」,最終傳給老師 | 將請求發送者與接收者解耦,多個對象組成鏈,逐個處理或傳遞 | 鏈路動態組裝;Servlet Filter、Spring Interceptor、Log4j Appender 均為鏈 |
| Command 命令 | MM 寫紙條讓弟弟送給我,紙條封裝了「請我吃飯/買包」等命令 | 將請求封裝為對象,支援參數化、排隊、日誌、撤銷、宏命令 | Receiver 執行邏輯,Command 封裝調用,Invoker 觸發;GUI 菜單、事務管理 |
| Interpreter 解釋器 | 《泡妞真經》腳本:步驟 1、步驟 2... 照著執行就能約會成功 | 定義語言文法表示並提供解釋器,處理特定領域語言 (DSL) | 文法規則映射為類層次;正則表達式引擎、SQL 解析器、模板引擎 |
| Iterator 迭代器 | MM 提要求:鑽石→別墅→法拉利→... 我一個個滿足,直到破產 | 順序訪問聚合對象元素,不暴露內部結構;支援多種遍歷方式 | Java Collection 框架核心;for-each 語法糖底層調用 Iterator |
| Mediator 中介者 | 四個 MM 打麻將,我當莊家算錢,贏的給我輸的找我,互不直接往來 | 封裝對象間交互,鬆散耦合,交互邏輯集中在中介者 | 減少多對多依賴;MVC 中 Controller、消息總線、事件總線均為中介者 |
| Memento 備忘錄 | 同時跟幾個 MM 聊天,備忘錄記錄每個聊天進度,防止說錯話翻車 | 在不破壞封裝前提下捕獲對象內部狀態,外部化存儲以便恢復 | Originator 創建/恢復 Memento,Caretaker 管理;撤銷功能、事務回滾 |
| Observer 觀察者 | 訂閱「公司 MM 情報郵件組」,Tom 發新情報自動推送到郵箱 | 定義一對多依賴,主題狀態變化自動通知所有觀察者更新 | 推/拉模型;Java 事件監聽、Guava EventBus、RxJava、Spring Event |
| State 狀態 | 約 MM 看電影:不喜歡→「有事」;一般→「行,帶同事」;喜歡→「幾點?看完去酒吧」 | 對象內部狀態改變行為,仿佛換了類;將狀態相關行為封裝到狀態類 | Context 持有 State 引用;狀態轉移邏輯可在 State 或 Context 中 |
| Strategy 策略 | 不同類型 MM 用不同戰術:文藝型→看展覽;吃貨→探店;戶外型→露營 | 定義算法族,封裝每個算法,使其可互換;算法變化不影響客戶 | Context 持有 Strategy 接口;Collections.sort(Comparator)、Spring ResourceLoader |
| Template Method 模板方法 | 《如何說服女生上床》八步曲:巧遇→破冰→追求→接吻→前戲→... 步驟固定,細節靠臨場發揮 | 定義算法骨架,將某些步驟延遲到子類實現;子類不改變算法結構 | 父類定義 final templateMethod() 調用 abstract primitiveOperations();Spring JdbcTemplate、HttpServlet |
| Visitor 訪問者 | 情人節送禮:找花店老板按 MM 喜好挑花,禮品店老板挑卡,我只負責派送 | 分離數據結構與操作,新增操作無需修改數據類;支援異構對象結構遍歷 | 雙分派:accept(Visitor) → visit(ConcreteElement);編譯器 AST、報表導出 |
創建:工廠建造原型單,抽象工廠族產品。 結構:適配橋接組合裝,外觀享元代理站。 行為:責任命令解釋迭,中介備忘觀察州,策略模板訪問者。
23 種設計模式是前人經驗結晶,用「追妹子」場景串聯僅為降低初學門檻。**真正掌握模式,需在實際重構中體會「封裝變化點、面向接口編程、組合替代繼承」三大核心思想**。建議:讀源碼(JDK、Spring、Guava)、寫重構 Kata、參與 Code Review、畫類圖講給同事聽——教會別人,才是學會的開始。