資料讀取與運作分開,從簡到繁

資料讀取與運作分開,從簡到繁

  1. 在我不同的專案,我都會面臨到同樣的問題,也就是如何將我的架構作良好的切割。
  2. 我們秉持著物件導向的觀念,使用繼承與封裝。
  3. 但組件式的觀念逐漸受到重視後,繼承似乎終將會走到深度繼承的問題。
  4. 深度繼承就是說當一個繼承樹必須處理過多繁雜的功能時,若非根部龐大,就是各分支出現重複無法共用的程式碼
  5. 若將讀取資料裝載在類別上,ParseXML()這個函式是用來讀入XML的資料,傳入一個XMLNode。
  6. 因此類別中就會include或知道XML的資料結構。
  7. 若有一天我們改使用JSon或其他種類的資料讀取方式,那麼這個類別就必須新增加ParseJSon()這個功能。
  8. 若此功能在繼承樹的根部,那麼所有類別都必須增加此功能,若是使用純虛擬(Pure Virtual),情況就更糟糕,必須修正所有的子類別等到都完成實作之後才能上傳程式碼(否則專案會編譯失敗)。
  9. 因此面對這個狀況我們通常只有幾個方案
    1. 勤奮的重構
    2. 想辦法阻止規格變動
    3. 吸取重構的經驗,在規格還不清楚之前捨棄先用物件導向的作法,亦即是提早體認到這種必然性。在功能與資料輸出入上分別做繼承,解構我們的繼承樹。
  10. 在這個例子中是這樣的架構:運作-資料-輸出入,與其將全部做一個繼承樹,不如將運作-資料,資料-輸出入作解構。甚至將運作/資料都切割開。
    1. 以此例,我們的運作FunctionClass倚賴資料,比如DataStruct(或是使用該程式語言的基礎資料結構)。而傳入資料的方式不 採用ParseXML,而統一使用SetupDataStruct( DataStruct _src )。如此一來運作的類別都使用統一的介面來設定。
    2. 第二部分則是分析資料,例如使用ParseXMLToDataStruct( XMLNode _node , DataStruct _src ),然後當資料讀取完畢再設定給運作物件FunctionClass。
  11. 若是有一天不使用XML時,我們要修改的部份就是另外製作ParseJSonToDataStruct( JSon _node , DataStruct _src )這個函式(群組),然後將原本使用ParseXMLToDataStruct()的部份修改為使用ParseJSonToDataStruct()。這 時只要ParseJSonToDataStruct()的實作正確,FunctionClass就完全不需要修改,也不需要知道外界的讀取媒介已經換掉 了。
  12. 承上,為了要達到更好的切換,我們還必須實作ParseToDataStruct( DataStruct _src )這個介面,讓外界完全不用知道內部使用的媒介的,只需要在初始化的時候切換設定ParseSystem pSys = new ParseSystem_XML,或是ParseSystem pSys = new ParseSystem_JSon。
  13. ParseSystem_XML::ParseToDataStruct()導到ParseXMLToDataStruct() 這個函式。
  14. ParseSystem_JSon::ParseToDataStruct()導到ParseJSonToDataStruct() 這個函式。
  15. 因此這個系統的演進會像這樣

Type 1

God使用FunctionClassBase1::ParseXML()
FunctionClassBase1知道XML
資料讀取與運作分開1

Type 2

God必須改使用FunctionClassBase2::ParseJSon()
FunctionClassBase2知道XML而且還知道JSon
資料讀取與運作分開2

Type 3

God必須切換使用ParseXMLToData()到ParseJSonToData()
FunctionClassBase3不用改變,也不需要知道現在用的是XML或JSon。
資料讀取與運作分開3

Type 4

God只需要修改初始化的地方改使用不同的ParseSystem,執行時不需要知道現在用的是XML或JSon。
資料讀取與運作分開4

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s