3 分鐘吃透開閉原則,架構設計築基必知必會

ITPUB社群發表於2023-10-30

來源:mikechen的網際網路架構


在開發專案時,幾乎都會再三強調開閉原則

開閉原則是物件導向設計中“可複用設計”的基石,它可以在不破壞現有功能的情況下,去擴充套件原有程式碼解決了軟體開發中的兩個問題:可擴充套件性可維護性

在設計模式的 6 大原則中,如果說開閉原則是精神領袖(抽象類),那麼其它設計原則,則是它的具體形態(具體實現類)。

3 分鐘吃透開閉原則,架構設計築基必知必會


今天我們深入開閉原則,本文內容包括:

  • 什麼是開閉原則

  • 開閉原則的 UML 類圖

  • 開閉原則的設計背景

  • 開閉原則的應用示例

  • 兩大方法避免違反開閉原則

  • 架構設計:預留擴充套件點思路


大家好,我是 mikechen。

開閉原則是良好架構設計的基石,非常重要。方便大家系統學習,我已將本文歸納到《阿里架構師進階專題合集》需要的同學,拉到文末自取

3 分鐘吃透開閉原則,架構設計築基必知必會


01
   什麼是開閉原則

開閉原則,英文全稱 Open/Closed Principle。

開閉原則是指一個軟體實體(類、函式等),應該 對擴充套件開放對修改封閉

1)對擴充套件開放(open for extension)

是指允許元件模組功能的擴充套件。

當需求發生變化時,可以透過對模組進行擴充套件,來實現新的需求。

2)對修改封閉(closed for modification)

是指對原有程式碼的修改封閉。

當元件模組功能進行擴充套件時,不應該修改原有程式碼。


02
  開閉原則的 UML 類圖

3 分鐘吃透開閉原則,架構設計築基必知必會


03
  開閉原則的設計背景

業務需求是動態變化的。如果每次需求變化都要修改程式碼,就會增加程式碼的複雜性、錯誤機率和維護成本。


開閉原則透過實現一個熱插拔的效果,在不破壞現有功能、不透過修改原有程式碼的情況下,採用擴充套件軟體實體的行為來實現需求,讓系統可維護可擴充套件可複用


04
  開閉原則的應用示例

抽象化開閉原則的關鍵。

為了滿足開閉原則,需要對系統進行抽象化設計。

在 Java 中,我們可以為系統定義一個相對穩定的抽象層,再將不同的實現行為移至具體的實現層中完成。

如果需要修改系統,無須對抽象層進行任何改動,只要增加新的具體類,就能實現新的需求,在不修改已有程式碼的基礎上擴充套件系統的功能,滿足了開閉原則的要求。

假設:

我們要實現一個繪製圖表的功能,支援多種圖表顯示方式,例如柱狀圖、餅狀圖...等多種圖表。

系統結構:

3 分鐘吃透開閉原則,架構設計築基必知必會

在 ChartDisplay 類的 display() 方法中,存在如下程式碼片段:

3 分鐘吃透開閉原則,架構設計築基必知必會

上面程式碼中,

如果需要增加一個新的圖表類(例如折線圖 LineChart),就需要修改 ChartDisplay 類的 display() 方法的原始碼,增加新的判斷邏輯,違反了開閉原則

為了滿足開閉原則,現在我們重構系統。

1)增加一個抽象圖表類 AbstractChart,將具體圖表類作為它的子類;

2)ChartDisplay 類針對抽象圖表類進行程式設計,由客戶端來決定使用哪個具體圖表。

重構後,系統結構是這樣的:

3 分鐘吃透開閉原則,架構設計築基必知必會

我們引入了抽象圖表類 AbstractChart,且 ChartDisplay 針對抽象圖表類進行程式設計,並透過 setChart() 方法由客戶端來設定例項化的具體圖表物件。

在 ChartDisplay 的 display() 方法中,呼叫 chart 物件的 display() 方法顯示圖表。

後續,如果還要增加新的圖表,不需要修改原來的程式碼,只需要將 LineChart 也作為 AbstractChart 的子類,在客戶端向 ChartDisplay 中注入一個 LineChart 物件就行了。


05
  修改原有程式碼,違反開閉原則?

那是否只要修改原有程式碼,就會違反開閉原則呢?

違反開閉原則的情況,通常是指頻繁且不必要的修改,這可能會增加bug機率,系統維護困難。

在修復錯誤、效能最佳化或其他合理情況下,修改程式碼本身並不違反開閉原則。

當業務規則改變時,完全不“修改”原有程式碼,這幾乎是不可能的。

例如:

類需要建立、組裝、做一些初始化操作,才能構建成可執行的程式。

這部分程式碼的修改,是不可難免的。


06
  如何避免違反開閉原則

一些思路,供大家參考:

1)在架構設計階段就要去關注系統的可擴充套件性事先預留擴充套件點

事先預留設計擴充套件點,可以在未來業務發生改變時,用最少的修改來滿足新的需求。

哪些情況需要預留擴充套件點呢?

需要預留擴充套件點的常見情況:

  • 對於相對確定的、可能短期內需要擴充套件的;


  • 對於改動對程式碼結構影響比較大的;


  • 對於可能用到、且實現成本不高的。


當然了,合理預留設計擴充套件點的前提,是需要對業務有足夠了解。

這個部分涉及到的實施細節、要素較多,本文只是提供參考思路,後續我再單獨更文介紹。

2)對於必須的合理修改,讓修改操作儘量更集中、更少、更上層,讓最為核心複雜的邏輯程式碼滿足開閉原則。


總結
  

開閉原則是物件導向設計中“可複用設計”的基石。它可以在不破壞現有功能的情況下,去擴充套件原有程式碼,讓系統可維護、可擴充套件、可複用。

事先合理預留設計擴充套件點避免違反開閉原則的關鍵在架構設計階段,就需要關注系統的可擴充套件性。

開閉原則既是面試高頻、也是必知必會,非常重要。

建議收藏備用,划走就再也找不到了。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2991738/,如需轉載,請註明出處,否則將追究法律責任。

相關文章