目錄
開發中用到的設計模式
工廠模式
設計理念
好處
體現的編程思想
適配器模式
概念
策略模式和適配器模式的區別
選擇策略模式而非適配器模式的原因
設計模式的開發原則
開發中用到的設計模式
在開發過程中,常見的設計模式會根據不同的業務場景和需求被廣泛使用,以下是一些例子:
- 單例模式:確保一個類只有一個實例,并提供一個全局訪問點。比如在配置管理類、日志記錄器等場景中,使用單例模式可以避免多個實例造成的資源浪費和數據不一致問題。
- 工廠模式:將對象的創建和使用分離,通過一個工廠類來創建對象。在需要創建多種不同類型對象的場景中,如創建不同數據庫連接對象時,使用工廠模式可以提高代碼的可維護性和可擴展性。
- 觀察者模式:定義了一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴它的對象都會得到通知并自動更新。常見于事件處理系統、消息通知系統等。
- 裝飾器模式:動態地給一個對象添加一些額外的職責。在 Java 的 I/O 流體系中就廣泛使用了裝飾器模式,通過不同的裝飾器類可以為基本的輸入輸出流添加緩沖、加密等功能。
工廠模式
設計理念
工廠模式的核心設計理念是將對象的創建邏輯封裝在一個工廠類中,而不是在客戶端代碼中直接實例化對象。客戶端只需要向工廠類請求所需的對象,而不需要關心對象是如何創建的。這樣可以將對象的創建和使用分離,提高代碼的可維護性和可擴展性。
好處
- 解耦對象的創建和使用:客戶端代碼只需要使用對象,而不需要關心對象的創建細節,降低了代碼的耦合度。例如,在一個游戲開發中,不同類型的武器有不同的創建邏輯,使用工廠模式可以將武器的創建邏輯封裝在工廠類中,游戲代碼只需要從工廠獲取武器,而不需要了解每種武器的具體創建過程。
- 提高代碼的可維護性:當對象的創建邏輯發生變化時,只需要修改工廠類的代碼,而不需要修改所有使用該對象的客戶端代碼。比如,如果要修改某個對象的初始化參數,只需要在工廠類中進行修改即可。
- 便于擴展:當需要添加新的對象類型時,只需要在工廠類中添加相應的創建邏輯,而不需要修改客戶端代碼。例如,在一個圖形繪制系統中,如果要添加一種新的圖形類型,只需要在圖形工廠類中添加創建該圖形的方法。
體現的編程思想
工廠模式體現了面向對象編程中的 “依賴倒置原則” 和 “開閉原則”。依賴倒置原則強調高層模塊不應該依賴低層模塊,兩者都應該依賴抽象。工廠模式通過抽象工廠和具體工廠的設計,使得客戶端代碼依賴于抽象的工廠接口,而不是具體的工廠實現類。開閉原則要求軟件實體(類、模塊、函數等)應該對擴展開放,對修改關閉。工廠模式在添加新的對象類型時,只需要擴展工廠類,而不需要修改已有的客戶端代碼,符合開閉原則。
適配器模式
概念
適配器模式是一種結構型設計模式,它允許將一個類的接口轉換成客戶端所期望的另一個接口。適配器模式可以讓原本不兼容的類能夠一起工作。常見的有類適配器和對象適配器兩種實現方式。例如,在 Java 中,將一個舊的日志記錄類的接口適配成新的日志框架的接口,就可以使用適配器模式。
策略模式和適配器模式的區別
- 目的不同
- 策略模式:主要用于定義一系列的算法,并將每個算法封裝起來,使它們可以相互替換。策略模式讓算法的變化獨立于使用算法的客戶端。例如,在一個電商系統中,對于不同的促銷活動(如滿減、折扣、贈品等)可以使用策略模式,將每種促銷算法封裝成一個策略類,客戶端可以根據不同的需求選擇不同的策略。
- 適配器模式:主要用于解決接口不兼容的問題,使原本不兼容的類能夠協同工作。例如,將一個第三方庫的接口適配成自己系統所需的接口。
- 使用場景不同
- 策略模式:適用于需要在運行時動態選擇不同算法的場景,算法的選擇由客戶端決定。
- 適配器模式:適用于需要復用已有的類,但該類的接口與當前系統不兼容的場景。
選擇策略模式而非適配器模式的原因
如果需求是在多個可互換的算法中進行動態選擇,以滿足不同的業務場景,那么策略模式是更合適的選擇。而適配器模式主要是解決接口不兼容問題,如果沒有接口不兼容的情況,使用策略模式可以更好地實現算法的封裝和替換,提高代碼的靈活性和可維護性。例如,在一個圖像處理系統中,對于不同的圖像壓縮算法(如 JPEG、PNG 等),使用策略模式可以方便地在不同算法之間切換,而不需要考慮接口不兼容的問題。
設計模式的開發原則
設計模式遵循一些基本的開發原則,這些原則有助于提高代碼的可維護性、可擴展性和可復用性,以下是一些常見的原則:
- 單一職責原則(SRP):一個類應該只有一個引起它變化的原因。也就是說,一個類應該只負責一項職責。例如,一個用戶管理類應該只負責用戶的增刪改查操作,而不應該同時負責用戶的權限驗證和日志記錄等其他職責。
- 開閉原則(OCP):軟件實體(類、模塊、函數等)應該對擴展開放,對修改關閉。即當需求發生變化時,應該通過擴展代碼來實現,而不是修改已有的代碼。例如,在一個圖形繪制系統中,當需要添加新的圖形類型時,應該通過擴展圖形類和繪制方法來實現,而不是修改已有的圖形繪制代碼。
- 里氏替換原則(LSP):子類可以替換父類并且不會影響程序的正確性。也就是說,子類應該能夠完全替代父類,并且不會破壞程序的原有功能。例如,在一個動物類層次結構中,子類貓和狗應該能夠替代父類動物,并且不會影響程序的正常運行。
- 依賴倒置原則(DIP):高層模塊不應該依賴低層模塊,兩者都應該依賴抽象。抽象不應該依賴細節,細節應該依賴抽象。例如,在一個電商系統中,訂單處理模塊(高層模塊)不應該直接依賴具體的數據庫操作類(低層模塊),而是應該依賴一個抽象的數據庫操作接口。
- 接口隔離原則(ISP):客戶端不應該依賴它不需要的接口。一個類對另一個類的依賴應該建立在最小的接口上。例如,在一個系統中,如果一個客戶端只需要使用某個接口的部分方法,那么應該將這個接口拆分成多個更小的接口,讓客戶端只依賴它需要的接口。
- 迪米特法則(LoD):一個對象應該對其他對象有最少的了解。也就是說,一個類應該盡量減少與其他類的交互,只與直接的朋友進行通信。例如,在一個社交網絡系統中,一個用戶類應該只與直接相關的好友類、消息類等進行交互,而不應該與其他不相關的類進行過多的交互。