為什麼國內那麼多公司亂用 C# 的三層架構?
發現國內好多用 C# 的公司,都喜歡三層架構。通常他們是建三個文件夾,命名為BLL、DAL、Model,再通過代碼生成器生成一大堆代碼,數據邏輯都要求使用存儲過程。這樣造成了一大堆多餘的代碼,修改麻煩,性能差。可是他們迷信這樣運行速度快。我經過測試後,發現一個簡單邏輯經過這樣的包裝速度完全快不了,並且他們根本不了解三層(數據,邏輯,界面)是什麼意思,他們以為就是建三個文件夾,造成這種錯誤用法是什麼原因?最初這樣錯誤使用的是誰?是誰推廣的?
最近又有人看這個答案,正好更新一下。
又工作這麼多年,還真碰到要把所有Oracle資料庫全換成NoSQL的事情了-_-bb,反正我們的系統都沒有DAL層,索性都按服務化的方式重新設計了。
大系統的架構是服務和領域之間怎麼交互,做畢設的時候「三層」才算架構-_-bb
知乎的老司機肯定都知道要干這倒霉事的公司是哪家了。
——————————原答案——————————
做了8年的http://ASP.net和C#了,其中5年是在和BLL DAL Model結構較勁。
首先這中 BLL+DAL+Model,根部不算三層架構,和MVC也相差甚遠。 基本上以我的經驗看,建立出BLL+DAL的,100%都是WebForm。他們甚至還有一層,混雜著伺服器控制項和事件驅動的aspx頁面。
單獨說回問題里的BLL DAL Model這3個玩意。 他們為什麼這麼搞呢,其他答案里說的PetShop實例是一個理由,第二個理由就是大學一幫老師一直灌輸面向對象要解耦,網站開發要分層。當然他們自己沒做過任何大型互聯網web項目。
說回這個, BLL DAL Model 再加上存儲過程(SP),這麼設計的人都是基於一個幻想——我分層以後,那怕SQLServer換成了Oracle,我們NB網站架構只要替換一個DAL層(甚至他們搞出IDAL介面)。 如果我們的表單處理邏輯要改動,我們上一個新的BLL層對象(當然他們還有IBLL介面),不用加班直接上線。 那怕資料庫內部schema發生了變化,只要我SP輸入輸出保持一致,那幫寫C#的人甚至不知道發生什麼。
當然我在工作中,從沒見到能直接替換 DAL和BLL 以匹配新架構的。甚至我從來沒遇到要把SQLServer替換為Oracle的項目方案。但是這套imba的架構,我們已經有了。
在延伸下去,培訓新員工的時候,創建一個新站點的時候,你要是不把BLL DAL先建好,都不好意思把代碼提交到代碼庫,否則還得落個不懂網站分層的惡名。 所以我見過了太多下面的代碼:
public insertOnBLL(Object obj) {
DAL dal = new Dal(); return dal. insertOnDAL(obj);}
甚至寫出這個的人,從來沒思考過題主的問題,反而還沉浸在自己的分層幻想里。
至於webform,基於當時對互聯網發展和編程模型的考慮,微軟設計出來以後就一直沒有拋棄。 但是現在,它已經不適用於任何面向最終用戶的網站開發了。
最初是Delphi,而且Delphi的三層就是這麼定義的,後來http://ASP.NET的三層也是這麼定義的。
當然了這一點都不會「造成了一大堆多餘的代碼,修改麻煩,性能差」,只能說他們聽到的宣傳出現了偏差,所以寫出了圖樣圖森破,桑堂拿衣服的代碼。補充一點。根據我看到的情況來看,這種三層架構經久流傳,實際上有個來源的。
那就是畢業設計。
大學的計算機系中,畢業設計用到的項目,因為各種原因,是一代代學生之中不停的流傳的。
不少的同學,到了畢設的時候,會設法從同學那邊拿一些項目過來,而這些項目來源往往很古老,也許是多代之前的項目源代碼,採用的也是極為老式的架構設計。就是題主說的BLL+DAL+Model
做完畢設的同學,真正學會的第一個項目,第一種設計結構也就是三層結構。
這樣的同學,到了軟體公司里,如果無人帶領,自然的會把這些習慣帶過去。
這個鍋C#不背。
WebForm強行把web應用封裝成單機GUI的形式很不科學,所以很少在其它框架中見到。能見到的基本都是MVC,我以下敘述也都是針對MVC的。
首先,對於一個Web應用,要是讓我寫的話,我肯定也開三個目錄,template、controller和model,再來兩個文件main和config。
web框架的封裝已經非常完備,你不這麼干也得這麼干。你只需要知道(數據,邏輯,界面)是幹嘛用的,怎麼交互。框架給你提供了模板引擎和orm,你偏不用偏要寫到一起,你不是傻嘛?你自己手寫出來的程序未必健壯。你不用模板引擎,非得直接拼接html,各種滲透遲早會教你做人。同理不用orm,直接用資料庫驅動構造sql,數據表的變動遲早會教你做人。
解耦的過程本身就不是為性能考慮的,而是職責單一分工明確之後提升開發效率。寫頁面的人一般和寫業務邏輯的人是兩個人。分離之後,只要你寫一個我寫一個拼起來就好了,提升效率,不會出現兩個人對著同一個文件改來改去的情況。同時這樣也助於提升代碼的可讀性和可維護性。在view裡面摻雜一大堆邏輯代碼能看?去看早年的asp吧。
目前來看,MVC對於Web開發應該還是真理,不爽不要玩,就是這樣。
---------------------------
至於WebForm為何是反模式,見這篇文章:Why MVC is Better?(翻譯)。WebForm背後的邏輯是這樣的
首先,對軟體分層,是有必要的,不管是從可維護性角度,還是從解耦的角度。
其次,被濫用,這個是的,很多人,並非真正理解分層的含義,就在照葫蘆畫瓢,照虎畫貓。
分層,必須真正的對項目有利,不論是提高開發效率,還是可測試性,可維護性還是降低開發難度。這是架構師應該平衡各項之後做出的設計。清一色的所謂三層,確實有濫用之嫌。
然後,回答中,大量的人,把題主所謂的傳統意義的三層和MVC混在了一起。這些答主,你們也屬於濫用層次模型的一類人。相信你們也都習慣把業務邏輯放到controller里,甚至你們會覺得MVC的M和ORM里的M是同一個東西,然後還覺得MVC真牛逼,比三層架構好多了~而且,傳統意義上的三層指的是UI(展示層)+BLL(業務邏輯層)+DAL(數據訪問層);MVC屬於UI層,是UI層的具體實現,它和三層架構沒有替代關係。MVC在整個Web應用架構中,地位和WebForm是一致的,它對WebForm是替代關係。
針對軟體的設計和架構,分層是需要的,對於略上規模的項目,就可以說是必要的。很多時候,甚至根據需要,會有更多的層次。當然,可以把更多的層次理解為三層架構中的細分,就像UI層的實現,可以細分為MVC/MVVM等層次。BLL層也許會根據業務需要,從業務邏輯上細分出來。而DAL也可以做文章,你可以直接調用http://ADO.NET訪問資料庫,但也可以用EF作為DAL使用。然而,也許你會發現,從性能考慮,應該加一層緩存。數據寫入也先寫入內存,然後批量入庫,來提高數據訪問性能。接著,自然就牽涉到數據一致性,這樣一個數據持久層(PDL)又出現了,用以協調資料庫和緩存之間的關係。如果項目比較大,用到了分散式存取,那麼協調各個機器之間的數據,又可以再加一層了~~
可以看到,具體用幾層,怎麼用,這是根據實際具體需要決定的,而不是用公式去套。就和學習設計模式一樣,這是對經驗的總結和應用,而不是萬能公式。
他們只會這個。
因為又簡單又暴力,關鍵時刻居然還有奇效,況且效率哪有你說得那麼低,這種簡易的架構新手又能寫老鳥也能寫,無論是開發效率、可維護性以及運行效率都比動不動就自認為逼格很高的上XXX框架的高到不知哪裡去了。
所以最後還是那句,別學會了舞刀弄槍就嘲笑那些玩匕首的,誰知道人家是不是阿薩辛啊。
你也說了,對於簡單的邏輯,改起來很麻煩。請注意,簡單二字很關鍵。
如果題主碰到比較複雜的邏輯,你就會感受到三層架構及設計模式的好處了。曾經做過一套視頻物聯網監控平台,業務邏輯還是很複雜的,多種類型,多路,多品牌/協議,多種參數,多種報警類型,多區域,多級聯網,多層組織架構,多用戶管理,多伺服器管理等等。碰到類似需求,我估計你會主動要求惡補設計模式,而不是嫌他麻煩。
為了提高代碼可維護性,可擴展性等,除了三層架構,我們還用了諸如類工廠(主要用於創建不同類型視頻前端介面),反射(解藕),適配器(不同類型數據處理)等設計模式。其實也是團隊成員在長期研發的過程中,碰到了很多問題以後,總結出來的。如果我們不這麼做,代碼早就成義大利麵條了。要不要用三層架構或其他設計模式,完全取決於你們的業務,同時需要考慮擴展性。如果只是簡單業務邏輯,採用最直接的辦法解決問題或許更合適。但如果業務流程比較複雜,而且擴展性可維護性很重要,那麼設計模式這一關是必須過的。你見到代碼不會是動軟生成的吧。
很多人對這種「三層架構」要求太嚴苛了。相當長時間我對其也很反感,覺得很low,看很多實習生甚至畢業1,2年的簡歷里如果寫了什麼「熟悉三層架構」,心裡是會減分的。但後來我想通,這本來就是一個引領初學者入門的玩意兒,非說要它不能做到解耦的目的,那很正常啊,項目上的解耦本來就是一種高級些武功,你怎麼指望剛開始涉足的人能真正的理解呢。像DDD這種方式難道不是需要有相當開發經驗才能真正弄懂的?不應該是在用了三層,慢慢項目大了,被噁心到了,才想尋求的解決方案?
其實小到一個項目代碼層級的構建,大到一個工程的運轉,都是面向"人"的,都是為了解決人們懶惰,易出錯,記性差這些「原罪」而創造的。從這點看三層並非一無是處,至少在一定代碼量級,符合人類的思維方式,可以節省各方面的成本。還有有些人總提性能,速度...毫無上下文,這不是經典的耍流氓模式嘛?
代碼大全上對此有很好的回答:架構應該描述所有主要決策的動機。謹防「我們向來這麼做」這種自認為有理的說法。
有這樣一個故事,Beth做魚要去頭去尾,她丈夫問她為什麼這麼做,她說她不知道,要問她的母親,她母親也說不知道,要問她的母親,她母親的母親說:我不知道你為什麼要去頭去尾,我這麼做是因為我的鍋太小了
造成這種錯誤用法是什麼原因?最初這樣錯誤使用的是誰?是誰推廣的?
原因是:需求不穩定最初錯誤使用的人是誰:沒有被錯誤使用是誰推廣的:是NB的架構師架構必須要理由才要存在,是為了解決性能瓶頸呀,還是要解決需求易變更啊,還是要並行開發呀,或者是需求不明呀。
像三層架構這種經典的架構,現在不適合你們的系統,在我看來大多是因為最開始需求不明而導致的,既然需求不明,那麼就要選擇一個容易修改並且熟悉的架構,所以選擇三層是很保守的決定,並沒有錯,這樣耦合度低,可以很好的面對需求變更,也容易並行開發。
如果像Helloworld這樣明確的需求,很少有人用三層架構吧這種架構解決的核心問題是 業務分離 和 分工合作 吧,性能的考慮應該是靠後的
如果說能夠在進行大型軟體開發的時候通過這種架構降低人與人合作的成本開銷,並且節約的開銷能夠值回票價(性能之類的),那就沒啥可說的了
這是用一部分性能換取團隊的效率。不過一般用這種架構的,效率大多都是在IO上比較吃緊吧,感覺用存儲過程也無所謂,要看具體的代碼怎麼設計了,如果最後寫出來的代碼,不能很好支持未來的重構,那實際上就- - 按了葫蘆起了瓢了吧。為了三層而三層。
我所知道的是:把業務邏輯寫成存儲過程是因為這種做法可以很方便地實現用戶的需求變更。雖然性能很差,出了bug也沒法調試,但由於系統本身很簡單,這些毛病也就不會造成什麼實際的影響。在小型應用系統上,這樣做其實挺合適的。當然,莫名其妙的3層估計就是人云亦云了。
架構分層不是為了」運行速度快「,是為了」開發速度快「。有一個清晰的架構能節省大量的後續運維和再次開發的時間和成本。而三層架構是一個很經典很好用的範式。
MVC叫三層架構是么?我不是很了解。
但是開發過程努力去找好的開發實踐是對的,當然,很多菜鳥可能根本不理解好的開發實踐好在哪裡。但是,就算不用所謂的三層架構了,這些菜鳥一定能把項目做好么????這個說到底不是用了什麼工具的問題,是用工具的人不懂怎麼來完成該完成的任務。。。。。