目錄
一、設計模式的定義
二、設計模式的三大類別
三、設計模式的原則
四、主要設計模式目錄
4.1?創建型模式(Creational Patterns)
4.2?結構型模式(Structural Patterns)
4.3?行為型模式(Behavioral Patterns)
一、設計模式的定義
設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。這些模式代表了最佳實踐,通常由有經驗的面向對象的軟件開發人員采用,以解決在軟件設計過程中經常遇到的一般問題。
設計模式提供了一種通用的語言和框架,使得開發者可以更高效地溝通復雜的系統架構,并且允許他們復用已有的解決方案來避免重新發明輪子。每種設計模式都描述了一個在軟件開發中不斷重復出現的問題,以及解決這個問題的核心思想。它們有助于提高代碼的可讀性、可維護性和可靠性,并使軟件工程更加工程化和規范化。
二、設計模式的三大類別
設計模式分為三大類:創建型模式(關注對象的創建)、結構型模式(關注對象之間的組合)和行為型模式(關注對象之間的交互和職責分配)。
大家在看一些資料的時候,會發現,有人特意提到J2EE類設計模式。這通常指的是在Java 2平臺企業版(Java 2 Platform, Enterprise Edition,簡稱J2EE)中使用的一系列設計模式。這些設計模式是針對開發企業級應用的特殊需求而提出的,它們可能并不屬于經典的Gang of Four (GoF)設計模式分類中的三大類:創建型、結構型和行為型。
因此,說“J2EE設計模式”是一種單獨的設計模式類別或子集是合理的。這主要是因為J2EE應用程序有其獨特的架構特點和挑戰,比如處理多層體系結構、分布式計算、事務管理、安全性等。為了解決這些問題,開發者們總結了一系列特定于J2EE環境的最佳實踐,這些實踐有時被稱為“J2EE設計模式”。
需要注意的是,隨著技術的發展,特別是Java平臺從J2EE到Java EE(Java Platform, Enterprise Edition),再到現在的Jakarta EE(由Eclipse基金會維護的企業級Java規范),一些早期與J2EE相關的模式可能會發生變化或不再適用。同時,新的模式也可能出現以適應新的技術和框架。
比如,大家都熟知的MVC設計模式,這可是初學JAVA必須領會的模式,比如經典的Struts框架,就是基于MVC設計模式。MVC(Model-View-Controller)模式是軟件工程中的一種經典架構模式,它在J2EE時代就已經被廣泛采用,并且對后續的Web開發框架和企業級應用有著深遠的影響。然而,隨著技術的發展,尤其是從J2EE到Java EE再到Jakarta EE的過程中,許多新的編程模型和框架出現了,它們提供了不同的方式來組織和管理應用程序的結構。
雖然 MVC 仍然是一種有效的設計原則,但它可能不再像以前那樣直接映射到現代 Java 框架中的組件。例如,在Spring框架中,盡管基本的概念類似于MVC,但實現方式卻有所差異,比如通過DispatcherServlet處理請求、使用@Controller和@RequestMapping注解來定義控制器行為等。
此外,其他現代前端框架,如AngularJS、React或Vue.js,它們也采用了類似的模式,但具體實現和分工與傳統的MVC有所不同。這些框架通常將視圖和控制器的職責合并在一起,而模型則負責處理數據和業務邏輯。
因此,說MVC模式不再適合所有情況并不完全準確。它的核心思想——分離關注點,仍然是現代軟件設計中的重要原則。只不過,隨著時間的推移,這種思想可能會以不同的形式體現出來,或者與其他模式組合起來形成更復雜的架構。開發者需要根據具體的項目需求和技術選型來決定最適合的架構模式。
三、設計模式的原則
以下是幾個在軟件工程中常用的設計原則:
1. 單一職責原則(Single Responsibility Principle, SRP)
? ?- 一個類或模塊應該只有一個改變的原因。
? ?- 這個原則強調了將代碼的職責劃分得盡可能清晰和獨立。
2. 開閉原則(Open-Closed Principle, OCP)
? ?- 對擴展開放,對修改關閉。
? ?- 這個原則建議通過抽象來實現代碼的可擴展性,而盡量避免直接修改現有代碼。
3. 里氏替換原則(Liskov Substitution Principle, LSP)
? ?- 子類型必須能夠替換其基類型。
? ?- 這個原則要求在繼承體系中,子類應當可以無限制地替代父類,并且不會導致錯誤或異常。
4. 接口隔離原則(Interface Segregation Principle, ISP)
? ?- 客戶端不應該被迫依賴于他們不需要的方法。
? ?- 這個原則提倡創建更小、更專業的接口,而不是大型、通用的接口。
5. 依賴倒置原則(Dependency Inversion Principle, DIP)
? ?- 高層模塊不應該依賴低層模塊,兩者都應該依賴抽象。
? ?- 抽象不應該依賴細節,細節應該依賴于抽象。
? ?- 這個原則有助于提高代碼的靈活性和可維護性。
6. 合成復用原則(Composite Reuse Principle, CRP)
? ?- 盡量使用對象組合,而不是繼承來達到復用的目的。
? ?- 這個原則鼓勵使用關聯關系來實現代碼復用,從而降低耦合度。
7. 迪米特法則(Law of Demeter, LoD)或最少知道原則
? ?- 一個對象應該對其他對象有盡可能少的了解。
? ?- 這個原則旨在減少模塊之間的耦合度,提高代碼的可讀性和可維護性。
8. 契約式編程(Programming by Contract, PBC)
? ?- 類和方法之間應有明確的約定(契約),包括前置條件、后置條件和不變條件。
? ?- 這個原則可以幫助確保代碼的正確性和可靠性。
9. 命令查詢分離原則(Command-Query Separation, CQS)
? ?- 方法要么改變對象的狀態(命令),要么返回結果(查詢),但不能同時做這兩件事。
? ?- 這個原則有助于提高代碼的可預測性和可測試性。
以上這些原則都是為了幫助開發者編寫出更加健壯、可讀、可維護和可擴展的代碼。在實際項目中,需要根據具體場景靈活應用這些原則,并與其他設計原則相平衡。
四、主要設計模式目錄
4.1?創建型模式(Creational Patterns)
創建型設計模式是用于處理對象的創建過程,它們將對象的實例化和使用解耦。以下是創建型模式中的一些主要模式:
1. 工廠方法(Factory Method)
? ?- 定義一個用于創建對象的接口,讓子類決定實例化哪一個類。
? ?- 使得一個類的實例化延遲到其子類。
2. 抽象工廠(Abstract Factory)
? ?- 提供一個創建一系列相關或相互依賴對象的接口,而無需指定具體的類。
? ?- 適用于需要提供多個相關的對象系列的情況。
3. 建造者(Builder)
? ?- 將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
? ?- 適用于需要生成的產品有多種表現形式或者組裝方式時。
4. 原型(Prototype)
? ?- 提供了一個從現有對象復制新對象的方法,而不是通過new操作符直接創建新的對象。
? ?- 當系統需要大量創建相似對象,而且創建過程很耗時的時候,適合使用此模式。
5. 單例(Singleton)
? ?- 確保一個類只有一個實例,并且提供一個全局訪問點。
? ?- 適用于只需要一個實例來協調系統的某些活動的情況。
這些模式的主要目的是隱藏對象的創建細節,使得代碼更加靈活和可擴展,同時減少了代碼之間的耦合度。在實際開發中,根據具體的需求和場景選擇合適的創建型模式可以使代碼更加健壯和易于維護。
4.2?結構型模式(Structural Patterns)
結構型設計模式關注于對象和類的組合方式,它們提供了如何將對象組織在一起以便更好地實現系統功能的方法。以下是結構型模式中的一些主要模式:
1. 適配器(Adapter)
? ?- 將一個類的接口轉換成客戶希望的另一個接口。
? ?- 使得原本不兼容的類可以一起工作。
2. 橋接(Bridge)
? ?- 將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
? ?- 提供了一種將抽象部分和實現部分解耦的方式。
3. 裝飾器(Decorator)
? ?- 動態地給一個對象添加一些額外的職責。
? ?- 提供一種比繼承更有彈性的替代方案來擴展對象的功能。
4. 外觀(Facade)
? ?- 為子系統中的一組接口提供一個一致的界面。
? ?- 它定義了一個高層接口,使得子系統更容易使用。
5. 享元(Flyweight)
? ?- 使用共享技術有效地支持大量細粒度的對象。
? ?- 減少內存使用并提高程序性能。
6. 代理(Proxy)
? ?- 為其他對象提供一種代理以控制對這個對象的訪問。
? ?- 可以用于創建輕量級的對象或延遲加載、權限檢查等場景。
這些模式通過改變對象間的組合關系,提高了代碼的復用性、靈活性和可擴展性,并降低了系統的復雜性。在實際開發中,根據具體的需求和場景選擇合適的結構型模式可以使代碼更加健壯和易于維護。
4.3?行為型模式(Behavioral Patterns)
行為型設計模式關注于對象之間的通信和責任分配,它們描述了如何在類或對象之間劃分算法的職責。以下是行為型模式中的一些主要模式:
1. 模板方法(Template Method)
? ?- 在一個抽象類中定義了一個算法的框架,而將一些步驟延遲到子類中。
? ?- 它允許子類在不改變結構的情況下重定義算法的特定步驟。
2. 命令(Command)
? ?- 將一個請求封裝為一個對象,從而使用戶可以使用不同的請求、隊列或者日志請求,同時還可以支持可撤銷的操作。
? ?- 通過將操作與接收者分離,使得新的請求類型易于添加。
3. 策略(Strategy)
? ?- 定義了一系列算法,并將每一個算法封裝起來,讓它們可以相互替換。
? ?- 策略模式讓算法的變化獨立于使用該算法的客戶。
4. 責任鏈(Chain of Responsibility)
? ?- 允許將請求沿著處理者鏈傳遞,直到被處理為止。
? ?- 消除請求發送者和接收者之間的耦合關系。
5. 狀態(State)
? ?- 允許對象在內部狀態變化時改變其行為。
? ?- 當控制流基于對象的狀態時,使用狀態模式更合適。
6. 觀察者(Observer)
? ?- 定義了一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都會得到通知并自動更新。
? ?- 提供了一種對象間的一對多發布/訂閱機制。
7. 訪問者(Visitor)
? ?- 表示一個作用于某元素結構中的各元素的操作。
? ?- 它使你可以在不修改各元素類的前提下定義作用于這些元素的新操作。
8. 備忘錄(Memento)
? ?- 在不破壞封裝性的前提下,捕獲一個對象的內部狀態以便稍后恢復它。
? ?- 提供了一種狀態保存和回滾的方法。
9. 中介者(Mediator)
? ?- 定義一個中介對象來封裝一系列的對象交互。
? ?- 降低了系統的復雜性和耦合度。
10. 迭代器(Iterator)
? ? - 提供一種順序訪問聚合對象的元素的方式,而不暴露其底層表示。
? ? - 支持以統一的方式遍歷各種數據結構。
11. 解釋器(Interpreter)
? ? - 給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
? ? - 當需要實現一個小規模的語言或者表達式解析時,適合使用此模式。
這些模式通過合理地組織對象間的交互,提高了代碼的復用性、靈活性和可擴展性,并簡化了復雜的系統設計。在實際開發中,根據具體的需求和場景選擇合適的行為型模式可以使代碼更加健壯和易于維護。
先整理這么多,后面我們有時間詳細一起學習幾個常用的設計模式。