你真的瞭解分層架構嗎?

你真的瞭解分層架構嗎?—寫給被PetShop......

文章轉載自:http://www.cnblogs.com/szp11/archive/2010/09/17/1829048.html
暱稱: 大肚小男人
ps:本文是做者與2010年寫的關於分層架構的理解,其中的一些理念值得學習。
 
NET平臺上的分層架構(不少朋友稱其爲「三層架構」),彷佛是一個長盛不衰的話題。常常看到許多朋友對其進行分析、探討、辯論甚至是抨擊。筆者在仔細閱讀了大量這方面文章後,認爲許多朋友在分層架構的理解上存在兩個比較大的偏頗:
1.沒有從本質角度去理解分層的內涵,而只是瞭解其表象。
2.對分層架構的理解過於狹隘,只是少數概念,而又不夠深刻。
許多朋友言「分層」則必稱「DAL」、「BLL」、「表示層」等概念,卻不知「DAL」的內部還有「Data Source 架構模式」、「Object-Relational Behavioral 模式」、「Object-Relational Structural 模式」等方面,而其中每一個方面下下又有諸多具體模式,如「Data Source 架構模式」又有「Table Data Gateway」、「Row Data Gateway」、「Acitive Record」等等。再說「BLL」,你們都知道「BLL」是「業務邏輯層」,但是什麼是「業務邏輯」?「BLL」又能夠構建爲「Transaction Script」、「Domain Model」、「Table Module」三種模式,各是什麼意思?另外,分層也不只只有「數據訪問層」+「業務邏輯層」+「表示層」這一種分法,諸如「服務層」、「持久化層」、「應用控制層」的概念朋友們是否真的熟悉呢。
形成這種現象,我想很大一部分緣由是由於大多數.NET平臺的開發者(包括我在內)理解分層架構是從Microsoft的PetShop開始的。由於PetShop是官方的Demo,因此被衆多.NET開發者奉爲聖經,甚至成了.NET平臺上分層架構的標準方案。我就曾看到許多朋友在個人博客中留下「分層架構仍是PetShop最經典」、「想學分層仍是看PetShop吧」、「你這是跟PetShop學得吧」這樣的留言。朋友們太崇敬PetShop了,卻忽略了一個事實:它僅僅是一個Demo。退一步說,即便它是一個實際應用的項目,這樣經過一個具體項目去定義一個抽象概念的方式也是不科學的。
舉個例子,一我的不知道「牛」是什麼東西,因而請教一位奶牛場管理員,管理員遷出一頭奶牛,告訴他:「這就是牛」。今後之後,若是有人問他「牛」是什麼,他就會告訴別人「牛」是一種體型龐大,行動笨拙,性格溫順,身上有黑白斑塊圖案,還有一個好大的咪咪,能夠擠奶供人喝。有一天,他據說西班牙有鬥牛這項運動,他大驚道:「這怎麼能夠!牛那麼溫順,怎麼能用來鬥呢!並且牛是用來擠奶喝的啊!」
故事中這我的犯了一個什麼錯誤呢?他把「具體的一頭奶牛」和「牛」這個抽象概念給劃等號了。他認爲牛就是「體型龐大,行動笨拙,性格溫順,身上有黑白斑塊圖案,還有一個好大的咪咪,能夠擠奶供人喝」。卻不知這世界上還有黃牛、水牛、犛牛、鬥牛、肉牛等各類牛。他沒能作到「透過想象看本質」從而造成抽象概念,而犯了「一葉障目」的錯誤。
其實,許多朋友之因此對分層架構理解片面或偏頗,是由於與故事中這我的犯了相同的錯誤。 當初,咱們不知道何爲「分層架構」,因而微軟給了咱們一個PetShop,說:「看!這就是.NET平臺下分層架構的產品。」因而咱們「恍然大悟」:「噢!這就是分層架構啊!」。就這樣,咱們把「分層架構」這樣一個內涵和外延都極大的抽象概念和一個具體的Demo劃了等號,從而也變成了故事中那我的——咱們言分層架構必稱DAL、BLL,咱們作項目必然依照PetShop方式架構……
咱們確實被PetShop「毒害」了。但這不是微軟的錯,更不是PetShop的錯,就像在故事中,咱們不能把罪責歸咎於奶牛場管理員或那頭奶牛。錯在咱們本身! 當微軟給咱們PetShop時,咱們應該在腦中清醒認識到:這是一個分層架構的Demo。而不是理解成了「這就是分層架構」。咱們應該鑽研、思考,從而抓住分層架構的本質,但是咱們沒有。 與其說咱們是被PetShop「毒害」了,倒不如說咱們是被本身、被本身那種不良的學習習慣毒害了。咱們僅看錶象,仍是隻看了一個表象,而後就冒然對分層架構蓋棺定論。而沒能透過想象看本質。因此,咱們一樣犯了「一葉障目」的錯誤。
以上的錯誤,筆者也曾經犯過!因此,在下文中,我想和朋友們一塊兒分享一下我在檢討本身的過程當中,悟出的一些心得體會,但願能借此幫助更多朋友儘快走出「一葉障目」。
洞悉分層的本質
咱們能夠討論如何分層,能夠討論分層的利弊,能夠討論分層有沒有價值……但在這一切一切討論以前,咱們要先弄清楚一件事:分層的本質是什麼?或者說:分層是怎麼來的?若是這個問題不明晰,那麼咱們其餘的討論猶如「浮沙之上築高臺」,再精闢的言辭,若是沒有一個牢固的基礎,也是站不住腳的。
想要了解分層的本質,就不得不說說分工。分工能夠說是勞動生產力上最大的改良,最初分工的好處體如今「比較優點」上,因爲各司其職,每一個人能夠從事其最擅長的勞動,再加上單純勞動所帶來的勞動熟練度提高和減小了更換勞動時的損失,使得勞動生產率大幅提高。然而,隨着社會的發展,咱們發現某些特殊形式的分工不但能夠提升生產力,還有另外一些好處!爲了理解這些好處,咱們舉個實際的例子。
今天是六一國際兒童節,一位母親想給她的女兒買一個奶油蛋糕做爲禮物。咱們知道,蛋糕須要麪粉、須要雞蛋、須要牛奶等等,還需呀通過一系列複雜的加工和包裝過程,可是這位母親不須要關心這些,她只要去附近的超市直接買就好了。而超市裏既沒有養雞場,也沒有奶牛場,更沒有種小麥的農民伯伯和烘焙蛋糕的工人師傅。這個簡單的「買蛋糕」場景,大約能夠用下圖表示。

圖一、製做蛋糕的分工
圖1大約說明了一個蛋糕是如何從到達顧客手裏的。能夠看到,製做蛋糕不是一個單一的勞動,須要許多的分工,若是自底向上看,主要的分工包括:基礎物質資料的種植生產、原料加工、蛋糕加工、商業銷售。並非全部分工都如上圖這樣,上圖所示的分工,有一些特色,下面總結一下。
1.下層不知道上層的存在。例如奶牛廠生產牛奶,它沒必要知道牛奶被拿去作什麼,可能被奶油廠收購去作奶油,也可能被雪糕廠收購了作雪糕,也可能被收購去作奶糖,總之,它只管完成本身的職責——生產牛奶,而對於它的上層一無所知。一樣,奶油加工廠只管生產奶油,它沒必要知道奶油被拿去作蛋糕仍是作摩卡咖啡。
2.每一層僅僅知道它的下一層(最後一層除外,由於最後一層沒有下一層),而不知道另外的下層。例如,蛋糕廠只需知道從麪粉廠、奶油廠和雞蛋廠提取麪粉、奶油、雞蛋就好了,而沒必要關心麪粉是怎麼來了、奶油是怎麼來的這些問題。
能夠說,符合以上兩點的分工就是分層架構的思想來源。下面說的稍微正式一點。 所謂分層思想,就是這樣一種分工:它將系統按不一樣的職責組織成有序的層次。其中,除最上層外,每一層僅提供若干服務供其相鄰的上層使用,但不知道上層的存在;除最下層外,每一層僅調用其臨近下層的服務。
因此,所謂「分層思想」,不過是一種特殊的分工形式。而計算機軟件架構中的分層思想,是將這一思想應用於軟件開發中的特例,而PetShop所使用的「DAL+BLL+PL」的方式,又不過是將這一思想應用於軟件開發中的特例的特例。例如,若是某個系統的業務很簡單,僅僅是增刪改查,那麼BLL就沒有做用,「DAL+PL」的方式就能夠很好完成,這也是很好的分層架構。再如,若是某個系統的業務很複雜,須要先規格化,再作運算,再作整理,那麼「DAL+規格化層+計算層+整理層+PL」這種五層架構也是很合理的啊。若是某個系統BLL所暴露的接口太繁雜,那麼使用Facade模式在BLL和PL之間加一個「Facade Service Layer」也是很正常的。再者,若是某個系統不須要數據存取功能,例如計算器程序,咱們只是想把表示和業務(計算功能)分開,那麼就沒有DAL了,「BLL+PL」就是合理的。因此,用分層的思想進行架構,本質是「將系統按不一樣職責組織成有序層次……」這一段話描述的,而不是簡單「將系統分紅DAL+BLL+PL」,更不是「按PetShop的方式進行架構」。
下面,摘錄一段Fowler在《Patterns of Enterprise Application Architecture》中對分層的定義:
When thinking of a system in terms of layers, you imagine the principal subsystem in the software arranged in some form of layer cake,where each layer rests on lower layer. In this scheme the higher layer uses various services defined by lower layer,but lower layer is unaware of the higher layer. Furthemore, each layer usally hides its lower layers from the layers above.
——Martin Fowler, 《Patterns of Enterprise Application Architecture》, P17
大體譯文以下:
當咱們說一個系統是分層架構的時候,你能夠把這個軟件想象成一個有不少層的蛋糕的樣子,其中每一層放在它的下一層上。較高層使用諸多較低層定義和提供的服務,但較低層並無察覺較高層的存在。另外,每一層都會對其上層隱藏更低的層。
——馬丁 福勒, 《企業應用架構模式》, P17
可是,這裏有一點須要聲明:雖說「DAL+BLL+PL」不等價於分層架構,而僅僅是一種實例。但同時咱們要清楚的認識到,這個方式之因此如此流行,以致於微軟的官方示例都這樣架構,是由於對於許多系統,特別是大中型MIS系統,這種架構方式是應該優先考慮的。在這一節中,筆者絕對沒有對「DAL+BLL+PL」進行批判的意思,相反,當開發系統時,這種方式能夠優先考慮,而後能夠根據系統的特色,進行必定得改良。筆者在本節所強調的是:不能把「DAL+BLL+PL」看作分層架構的本質,更不能和「分層架構」這個思想概念劃等號。
分層架構的利弊分析
在理解了分層架構的本質的基礎上,咱們才能夠放心大膽的對分層架構進行利弊分析。廢話少講,這一節咱們直接切入正題。
分層架構的優勢以下:
1.分離開發人員的關注。因爲某一層僅僅調用其相鄰下一層所提供的服務,因此,只要本層的API和相鄰下一層的API定義完整,開發人員在開發某一層時就能夠像關注集中於這一層所用的思想、模式、技術,這樣,就等同於將分工帶來的生產力提升優點引入軟件開發。又如買蛋糕的例子,做爲超市,只要知道下層API(如何從蛋糕廠獲取蛋糕)和本層須要實現的API(把蛋糕銷售給客戶),就能夠制定本身的業務模式很策略計劃了,而沒必要關心如何種小麥、如何磨麪粉、如何作奶油、如何作蛋糕等。這樣,超市只需進行商業運做,而沒必要進行產業運做,如此專注,必然提升業務水平。
2.無損替換。想象一下,若是某家奶牛場倒閉了,奶油加工廠也要跟着倒閉嗎?固然不會,它能夠迅速更換一家奶牛場,由於各個奶牛場均可以實現「提供牛奶」這項服務。再譬如,若是某天國家出臺政策,要求全部奶油廠必須從審查合格的奶牛場引進原料,剛好某奶油廠的合做牛奶供應商沒能經過審查,那麼,只要換一家經過審查的合做就好了。並且奶油廠內部的各個環節一動不用動,由於不一樣的奶牛場均可以提供「供應牛奶」這個服務。而若是奶油廠本身養牛生產牛奶,一旦遇到這個政策,還得本身去有關部門進行審查,調整相應業務流程,牽一髮而動全身。程序中一樣的道理,最常據說的可能就是遷移數據庫了。
3.下降了系統間的依賴。仍是蛋糕那個例子,若是某天蛋糕廠內部換機器了,或業務流程調整了,請問顧客須要關心嗎?顯然不用,由於顧客只調用超市提供的服務。而超市爲顧客隱藏了下面全部產業細節。若是每個顧客買同樣商品,都要了解這個商品從原料生產到成型再到銷售的一系列細節,豈不累死了。換作程序中,就如表示層只管調用業務層的服務,至於業務層下還有幾層?各類數據是怎麼來的?怎麼存的?是真實的仍是捏造的?都不須要了解,這大大下降了系統各職責之間的依賴。
4.複用。例如,你能夠去這個超市買東西,我也能夠去這個超市買東西。蛋糕廠能夠從麪粉廠提取麪粉,饅頭廠也能夠。這樣,一樣的層就能夠爲不一樣的上層提供服務,達到了複用的目的。具體到程序中,例如氣象局製做發佈了一個「Service Layer」,用於提供天氣預告信息。這樣新浪、搜狐這些網站能夠利用這個服務層提供的服務,製做天氣預告頁面,QQ也能夠利用這個服務在它的聊天工具上添加天氣預告,你本身作一個軟件須要用到天氣預告功能,也能夠調用氣象臺的「Service Layer」。
說罷優勢,再來談談分層架構的弊端:
1.級聯修改問題。這個問題在現實中很差比喻,但在程序中相信不少朋友都明白。例如,一我的事管理系統,原本查看人員信息只能分頁查看,而如今,須要增長一個功能:在分頁的同時還能分部門。例如,能夠查看「銷售部的前50我的」,這樣,爲了這個功能全部層都須要修改。
2.性能問題。原本直來直去的操做,如今要層層傳遞,勢必形成性能的降低。就如在購買蛋糕的例子中。顧客在享受分工帶來的便利時,也要承受因爲不一樣層的部門分佈各地而形成的蛋糕價格上升,這是由於分層增長了成本,如運輸、不一樣層間部門的協調管理成本等。
縱觀以上分析,分層架構有利有弊。這是必定得,世上任何事物都有利弊,因此,把「分層架構捧上天」和「一棍子打死」這兩種作法都是不明智也是不科學的。對待分層架構,咱們的態度應當是明晰其本質和利弊,而後根據具體狀況作出理性的分析和抉擇。
從上面的分析能夠看出,分層架構能夠下降層內變化的成本,而對於API的變化很是敏感。如在級聯修改中提到的「在分頁的同時還能分部門」的新需求,就是對API進行的變更。API的變更對於分層架構是致命的,修改起來難度很是大。因此,一個簡單的判斷法則就是: 若是您的系統層內頻繁變更(甚至整層替換)可能性很大,而API變更可能性很小,就使用分層;而若是API可能會頻繁變更,那就要謹慎使用分層架構了。
後面的話 其實,我想說的主要內容,就是前面三節了。不過仍是有些話,想和你們嘮叨嘮叨。 這篇文章,不是一篇技術文章,因此通篇不提技術細節,而只是想幫你們澄清對分層的誤解。最近看了不少對分層架構(或三層架構)的探討,其中以批判居多,有的甚至認爲分層就是個沒用的垃圾東西。我想,產生這種想法的人,大體通過了如下階段:據說分層,粗略學習分層、模仿使用分層、用得十分不爽、出來批判。 其實,任何技術都是客觀的,都沒有錯誤,錯誤在人,是人沒有正確使用,或沒有用到合適的地方。就像咱們不能批判刀片不適合劈叉,也不能批判柴刀不適合刮鬍子。一項技術想要發揮威力,關鍵要正確運用,而要正確運用,就須要有深厚的功底,須要咱們努力學習,勤于思考。這不是一朝一夕的事情,要有持久的毅力。咱們要爭取作一個善於用功、善於把握事物本質的人,而不是一個用刀片劈柴、用柴刀刮鬍子,而後大罵刀片和柴刀都是垃圾的人。 分層思想歷來就不是軟件架構中首先提出來的,咱們每天上網用到的網絡,都遵循OSI七層協議,網絡結構的設計是分層思想合理應用的一個典範。另外,在許多其餘工程技術領域,分層思想也是很廣泛的。因此,不要把分層當成計算機人士甚至軟件開發人士獨有的能力,相對那些領域,將分層應用於軟件架構的技術還很不成熟,還有許多事情等待咱們去作。
相關文章
相關標籤/搜索