近日看到了一篇關於反三層的文章,手也痒痒了,就犧牲些時間,拿出來把這個老得掉牙的話題拿出重談。
1. 什麼是三層
很多人愛把三層架構和MVC混為一談,但是我們可以從最簡單的角度去考慮他們的不同:
在設計模式中一般都會有這樣一章,MVC設計模式,而從沒見過哪本書中有寫過三層架構設計模式。
迴歸三層,三層一般來講分為兩類:
A. 物理上的三層架構
B. 邏輯上的三層架構
現在就逐個談起,來看下究竟三層是否要走開。
2. 邏輯三層架構
邏輯三層架構從概念上看很容易,使用者介面層,商務邏輯層,資料訪問層。每一層都有自己所專有的職責。
三層架構是一切企業級架構的核心,直至Petshop中的七層,或者是一般企業中的五層都是以三層做為一個中心,在這裡,我們可以說N=3。
使用者介面層專職顯示工作,與使用者直接打交道。
商務邏輯層用於做一些複雜的業務處理。
資料訪問層用於與資料庫做一個互動,做常規的增刪改查的操作。
這些很簡單,點到為止。
3. 物理三層架構
物理三層架構是以邏輯的三層架構為基礎的。如果沒有了邏輯的三層,就根本談不上物理三層架構的部署。
什麼是物理三層架構?
從簡單了說就是每一層都分別做成一個組件,如商務邏輯組件,業務實體組件,資料訪問組件等。
再到麻煩了一些就是構建分布式系統,例如將商務邏輯層與資料訪問分別部署再不同的伺服器上。
4. 再論預存程序
預存程序作為一個SQLAS,與每門語言一樣,也有著自己的優點和缺點。
來與資料庫打交道無非三個方法:
A. 在程式邏輯中書寫SQL語句,其中包含SQL字串拼接最為常見
B. 在資料訪問層使用ORM架構,在.NET項目中以LINQ TO SQL和NHibernate為主。(其實兩者在實際項目中都不常用)
C. 使用預存程序
我們來分析一下他們之間的優缺點:
在程式邏輯中寫SQL語句是很難處理複雜商務邏輯的,困難的引號匹配,複雜的字串拼接過程,以及字串拼接過程中的效率損失是我們不得不考慮的。
ORM架構是一個好辦法,這個我不報什麼懷疑意見,但是LINQ TO SQL略顯蹩腳的文法,讓常規程式員在C#和LINQ之間來迴轉換不是件容易事。NHibernate就不說了,這個在中國大多數公司來說還算是個非主流架構,而且與VS的整合不是很令人滿意。
於是,處理複雜邏輯,如複雜的交易處理時,預存程序幾乎成了唯一的方法。
但是,預存程序一樣有著他的致命缺點,就是他的移植性很差,
A. 當我們的項目更換資料庫時,我們就要把預存程序完整地去拷貝到另外一個資料庫,然後考慮他們的相容問題。
B. 當我們修改資料層存取碼時,我們需要動的不再是應用程式伺服器的代碼,而是資料庫端的代碼,這是稍顯痛苦的地方 。
5. 三層的優點
現在有人去質疑三層,讓三層走開,問題不在於三層。而在於他錯用了三層。好刀要用在刃上,否則,恐怕只會弄巧成拙。
那麼下面就說三層的優點究竟在哪?
A. 正如上面而言,邏輯上的三層是物理上三層的前提條件。
B. 三層可以讓團隊開發中,每個成員有著自己的關注點,而且利於小組成員的分工。
C. 重用資料訪問層和商務邏輯層
D. 多語言協作(如資料訪問層用vb,商務邏輯層用C#,情況很少見)
E. 一定程式上的易維護,但我個人認為這點體現的不明顯,就像那位兄弟講的那樣,如果修改一個欄位,需要在三層都進行修改。
6. 三層不三層
究竟是三層還是不三層,這一直是困擾很多人的問題。
正如每一種設計模式一樣,這些都是一把雙刃劍,用得好了會讓你很方便,但是用錯了卻是適得其反。
是否三層,要縱觀整個項目,然後去提前挖掘他的潛在變化點,然後再去想,如果這個項目用了三層對你有什麼好處。
如果你想不到,那麼就不要去三層。
常用三層的情況如下:
A. 產品型公司需要向上屏蔽底層細節,因此需要封裝好很多訪問以及商務邏輯,這個時候必須三層。
B. 項目很大,需要多成員合作,讓一個成員既關注頂層的商務邏輯,又要關注頁面美觀,還要去注意資料訪問的效率,這是不現實的。
C. 項目巨大,需要應用程式邏輯分布式。
7. 三層之擴充
在我所有的文章中,都在強調思想的重要性,我不喜歡被前人去限制住自己的思路,不喜歡輕易相信書上的觀點,除非被我證實過。本篇也是一樣。
究竟是三層,我覺得三層本就是一個思想,沒必要說這樣就是三層,那樣就不是三層,這就把知識學的太死了。
還記得國外哪位大師給AJAX下的定義:只要能夠提高使用者體驗的技術,我們就將之統稱為AJAX。
其實,我個人認為三層也是一樣:能夠讓我們的項目適應變化,可重用,方便程式員的架構方法,我們就可以稱之為三層。
8. 擴充三層分類
A. 簡化版三層:
當商務邏輯簡單時,就把商務邏輯層簡化,於是就形成了這樣的結構:
.aspx為使用者介面層 .aspx.cs為商務邏輯層 .cs單獨搭建資料訪問層
B. 一些變化
通常的公司都會有自己資料訪問類,就像Petshop中的SqlHelper。我們也可以把這單獨叫成一層,不過這都是概念問題了。
C. 分出商務邏輯和業務實體
對於很多項目來說,商務邏輯處理都是相對複雜的,說個簡單的,比如在登陸介面,當傳出密碼到存入資料庫,就需要一個加密的過程,我們就可以把這個過程封裝到商務邏輯層內。另外,比如一些複雜的流程處理,我們同樣可以在商務邏輯層去。
業務實體就不說了,這個很常見。
D. 無業務實體
在很多辦公OA的項目中,資料往往是無實體的,因為使用者可以根據自己的選擇去動態地構建資料庫表欄位,因此這個時候,業務實體就沒有存在的必要了。
E. 極端簡化
在很多小項目中,商務程序簡單,資料處理容易,更沒有一些複雜的操作,沒有團隊合作,那麼我們就沒有必要去分層。這個時候的分層只會讓我們的編碼量以及維護量更大。那麼這種情況算什嗎?
我之前提過這個概念,只要能夠讓我們的項目適應變化,可重用,方便程式員的開發,我就把他叫做三層,那麼這麼來說,這種最簡單的方式其實我們也能把他勉強叫成是“三層”吧。
9 . 總結
三層不三層,三層要怎麼三層,這本來就是一個很難去抉擇的問題。
所以,我還是那個觀點,適應變化的架構方式就是最好的方式。