2010年12月1日

LinQ對分層架構(UIL, BLL ,DAL)的影響

網路上看到LinQ的優點大都從O/R Mapping(ORM)的角度,或整合不同型態的來源,
對於我而言,其對分層架構的影響更大的多...

隨著開發的系統日漸龐大,
約在2003年,我們公司參考微軟的範例(duwamish)在幾個同事推動下導入了分層設計,
將系統大致切為User Interface Layer、Business Logical Layer、Data Access Layer三層,
這種做法的優點就不再贅述,這些年來也頗常見(或稱N-tier architecture),
但是,很多問題也因此發生。

舉例來說,
如果使用者要求在進入人事系統中,
單位主管除了看到人員列表外,還希望看到目前每個人的負責/完成專案數,以及簽/遲到狀況,
總務部門希望看到每個人的是否還有信件未領取,福利金是否繳交。

像這樣的需求實務上應該不少見,也不算不合理,
但在一般提到分層架構的範例或書籍卻相當少被提及。

就OO設計的單一責任(SRP)原則 ,人員列表、專案數與簽到、遲到明顯屬於不同邏輯,
但,難道開發人員能用『商務邏輯應該單一化』為由,
要求使用者一定要在不同的介面進行操作與查詢嗎?

簡單一點的做法(我指.Net架構中),
有人就在DAL中寫個很複雜的Query,把人員查詢、負責專案數、完成專案數、簽到...
全部 Join 起來,然後用 DataSet 或 DataTable 傳回去,
但這樣就違反了幾個原則:
  1. 將查專案數、簽到、遲到等不同的邏輯全混在一起,全無『高內聚,低耦合』可言。
  2. 查專案數、簽到、遲到等可能並不是單純的select table,其中有許多條件,這麼一來,等於在DAL放了許多的Bussiness Role。
  3. 只要介面又被要求修改,例如再加個請假天數,連DAL也要動,喪失分層架構的原意。
這些問題即使改用Typed DataSet也一樣,
更多了一個問題:難道要為人員+ 負責專案數+完成專案數... 多一個宣告Typed DataTable嗎?

為了能藉決這些問題,
我試過自己寫DataTable merge的工具程式(類似SQL Helper),
好讓 DAL能分別獨立的取得人員清單、專案數、簽到、遲到等資料,再於 BLL做合併。
看起來雖然好一些,但也常常有效能或功能仍然不夠的問題。

這個問題終於隨著LinQ面世,帶來了一絲曙光。

這不只是可以快速產生帶有Bussiness Rule的資料物件(指LinQ  to SQL),
並且有了一種能在BLL作資料運算的語言(不用自己來制訂)。
你可以維持DAL的單純化,分別提供人員清單、專案數、簽到、遲到等資料存取方法,
然後在BLL中取得後再進行條件過濾、合併(join)甚至 group等動作,
真正的讓『業務邏輯規則』集中在BLL。

我是說理論上是這樣吧!
實際上的效能等問題,可能過一陣子再來探討。