3 分鐘吃透開閉原則,架構設計築基必知必會
來源:mikechen的網際網路架構
在開發專案時,幾乎都會再三強調開閉原則。
開閉原則是物件導向設計中“可複用設計”的基石,它可以在不破壞現有功能的情況下,去擴充套件原有程式碼。解決了軟體開發中的兩個問題:可擴充套件性、可維護性。
在設計模式的 6 大原則中,如果說開閉原則是精神領袖(抽象類),那麼其它設計原則,則是它的具體形態(具體實現類)。
今天我們深入開閉原則,本文內容包括:
什麼是開閉原則
開閉原則的 UML 類圖
開閉原則的設計背景
開閉原則的應用示例
兩大方法避免違反開閉原則
架構設計:預留擴充套件點思路
大家好,我是 mikechen。
開閉原則是良好架構設計的基石,非常重要。為方便大家系統學習,我已將本文歸納到《阿里架構師進階專題合集》。需要的同學,拉到文末自取。
開閉原則,英文全稱 Open/Closed Principle。
開閉原則是指一個軟體實體(類、函式等),應該 對擴充套件開放、對修改封閉 。
1)對擴充套件開放(open for extension)
是指允許元件模組功能的擴充套件。
當需求發生變化時,可以透過對模組進行擴充套件,來實現新的需求。
2)對修改封閉(closed for modification)
是指對原有程式碼的修改封閉。
當元件模組功能進行擴充套件時,不應該修改原有程式碼。
業務需求是動態變化的。如果每次需求變化都要修改程式碼,就會增加程式碼的複雜性、錯誤機率和維護成本。
開閉原則透過實現一個熱插拔的效果,在不破壞現有功能、不透過修改原有程式碼的情況下,採用擴充套件軟體實體的行為來實現需求,讓系統可維護、可擴充套件、可複用。
抽象化是開閉原則的關鍵。
為了滿足開閉原則,需要對系統進行抽象化設計。
在 Java 中,我們可以為系統定義一個相對穩定的抽象層,再將不同的實現行為移至具體的實現層中完成。
如果需要修改系統,無須對抽象層進行任何改動,只要增加新的具體類,就能實現新的需求,在不修改已有程式碼的基礎上擴充套件系統的功能,滿足了開閉原則的要求。
假設:
我們要實現一個繪製圖表的功能,支援多種圖表顯示方式,例如柱狀圖、餅狀圖...等多種圖表。
系統結構:
在 ChartDisplay 類的 display() 方法中,存在如下程式碼片段:
上面程式碼中,
如果需要增加一個新的圖表類(例如折線圖 LineChart),就需要修改 ChartDisplay 類的 display() 方法的原始碼,增加新的判斷邏輯,違反了開閉原則。
為了滿足開閉原則,現在我們重構系統。
1)增加一個抽象圖表類 AbstractChart,將具體圖表類作為它的子類;
2)ChartDisplay 類針對抽象圖表類進行程式設計,由客戶端來決定使用哪個具體圖表。
重構後,系統結構是這樣的:
我們引入了抽象圖表類 AbstractChart,且 ChartDisplay 針對抽象圖表類進行程式設計,並透過 setChart() 方法由客戶端來設定例項化的具體圖表物件。
在 ChartDisplay 的 display() 方法中,呼叫 chart 物件的 display() 方法顯示圖表。
後續,如果還要增加新的圖表,不需要修改原來的程式碼,只需要將 LineChart 也作為 AbstractChart 的子類,在客戶端向 ChartDisplay 中注入一個 LineChart 物件就行了。
那是否只要修改原有程式碼,就會違反開閉原則呢?
違反開閉原則的情況,通常是指頻繁且不必要的修改,這可能會增加bug機率,系統維護困難。
在修復錯誤、效能最佳化或其他合理情況下,修改程式碼本身並不違反開閉原則。
當業務規則改變時,完全不“修改”原有程式碼,這幾乎是不可能的。
例如:
類需要建立、組裝、做一些初始化操作,才能構建成可執行的程式。
這部分程式碼的修改,是不可難免的。
一些思路,供大家參考:
1)在架構設計階段,就要去關注系統的可擴充套件性,事先預留擴充套件點。
事先預留設計擴充套件點,可以在未來業務發生改變時,用最少的修改來滿足新的需求。
哪些情況需要預留擴充套件點呢?
需要預留擴充套件點的常見情況:
對於相對確定的、可能短期內需要擴充套件的;
對於改動對程式碼結構影響比較大的;
對於可能用到、且實現成本不高的。
當然了,合理預留設計擴充套件點的前提,是需要對業務有足夠了解。
這個部分涉及到的實施細節、要素較多,本文只是提供參考思路,後續我再單獨更文介紹。
2)對於必須的合理修改,讓修改操作儘量更集中、更少、更上層,讓最為核心複雜的邏輯程式碼滿足開閉原則。
開閉原則是物件導向設計中“可複用設計”的基石。它可以在不破壞現有功能的情況下,去擴充套件原有程式碼,讓系統可維護、可擴充套件、可複用。
事先合理預留設計擴充套件點,是避免違反開閉原則的關鍵。在架構設計階段,就需要關注系統的可擴充套件性。
開閉原則既是面試高頻、也是必知必會,非常重要。
建議收藏備用,划走就再也找不到了。
以上
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2991738/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 依賴倒置原則就看這篇,7張圖解徹底吃透,架構設計築基必知必會圖解架構
- 必知必會的設計原則——介面隔離原則
- 2分鐘通俗理解迪米特法則,架構設計築基必看架構
- 設計模式必備知識點---六大設計原則設計模式
- 借降本增效之名,探索開閉原則架構設計架構
- 設計原則:開閉原則(OCP)
- 必知必會的Node-CLI開發基礎
- TiFlash 函式下推必知必會丨十分鐘成為 TiFlash Contributor函式
- SOLID架構設計原則Solid架構
- 設計原則之【開放封閉原則】
- 阿里P7架構師告訴你Java架構師必須知道的 6 大設計原則阿里架構Java
- MySQL 必知必會MySql
- Linux必會必知Linux
- git必會必知Git
- Redis 必知必會Redis
- ThreadLocal必知必會thread
- Activity 必知必會
- JSON 必知必會JSON
- HashMap必知必會HashMap
- Java程式設計師必備:微服務+開源框架+架構基礎+高效能架構+設計模式Java程式設計師微服務框架架構設計模式
- 開閉原則——物件導向程式設計原則物件程式設計
- 《JavaScript設計模式與開發實踐》原則篇(3)—— 開放-封閉原則JavaScript設計模式
- 五分鐘掃盲:程式與執行緒基礎必知執行緒
- notion database 必知必會Database
- Linux shell必知必會Linux
- Linux 程式必知必會Linux
- Android NDK 開發之 CMake 必知必會Android
- MySQL必知必會筆記——查詢的基礎知識MySql筆記
- 效能測試必知必會:Shell指令碼設計實踐指南指令碼
- 雲原生架構及設計原則架構
- 必知必會Java命令-jpsJava
- Redis 必知必會之 APIRedisAPI
- mysql必知必會筆記MySql筆記
- Mysql必知必會練習MySql
- HTTP 必知必會的那些HTTP
- 01-mysql必知必會MySql
- 常用技術必知必會
- 設計模式六大原則(六)----開閉原則設計模式