需求描述
一個比較復雜的頁面,界面中包含的元素數據來自於許多個有關聯或者無關聯的表,然后我們要做的就是將數據呈現在界面上。
10年前大概都是這么干的
直接寫一個復雜的SQL語句,返回一個包含所需數據的二維表,然后直接與界面開始綁定。
簡單、粗暴。
今天的現狀
信息化解決方案的普及,我們接到的企業應用項目很多都是在舊系統無法滿足需要的情況下擴展,業務功能也將建立在原來的基礎上變得更加復雜。
所以,為了解決系統復雜所帶來的困惑,人們開始使用分層架構。
分出數據訪問層,使得數據提供得以重用。分出業務邏輯層,使得業務邏輯得以重用。
遇到更加復雜的業務,使得領域驅動設計開始流行,它將更多的業務邏輯內聚在領域模型里面,使得更多的業務邏輯得以重用。
引出了問題
1、許多人使用了ORM工具之后,認為它只能處理簡單的功能,或者認為它適合做做界面上只有單個表的增刪改,總之認為它不夠靈活,其實ORM工具的Model只是一個業務層的東西,不是表現層的Model。
2、碰到這種界面元素復雜的問題,就覺得分層架構根本就是扯淡,有想直接上來一條SQL語句解決問題的沖動。
我們該如何解決
1、界面元素跟單個實體對應的情況。
這種情況在微軟官方的DEMO中經常出現,ASP.NET MVC 5+EF6能夠自動生成增刪改列表3個頁面,沒什么好說的。
經常容易誤導我們,以為MVC中的M指的只是實體類,其實M還可以指實體的服務類,實體的服務類里面包含業務邏輯的處理。
其實M指的是業務邏輯層,不一定只包含單個實體,很可能是多個有關聯的實體,或者叫聚合根。
2、界面元素跟多個有關聯的實體對應的情況。
這種情況就是上面提到的聚合根,業務層包含一定的邏輯,最后返回一個聚合根給控制器(C)。
視圖(View)只需要一個Model就能搞定,強類型使得你很容易就能夠點出它的依賴。
讓業務層做它該做的事情,別讓表現層的Controller搶了業務層的飯碗。
3、更為復雜點的,界面元素跟多個無關聯的實體對應的情況。
這種情況下,我們需要創建一個ViewModel,然后用它組合多個無關聯的實體。
把握一個原則,業務類對應的是業務模型,ViewModel對應的是每個View。
所以上面兩種處理方法只是界面元素簡單的情況下減輕工作量的做法,而理論上是需要一個View對應有一個ViewModel。
4、再復雜一點,或者不止一點。
好吧,真的足夠復雜的話,那就無視一切理論吧,原生SQL、存儲過程、無分層,隨便了。
業務邏輯寫在數據庫,還是寫在應用程序,這取決於縱向的負載均衡,需要智慧與經驗。
主題是表現層,所以不討論數據庫該不該處理業務邏輯的問題。
總結:
當界面元素比較復雜時,試着創建一個ViewModel來組合業務類去磨平它,而不是去抱怨MVC、ORM、分層架構不夠靈活。
本文轉載自燕十三的博客
原文標題:表現層的設計(二)——MVC如何處理復雜的界面元素