企業級應用框架(四)我的這個系列到底要說什么


前言

  這個系列已經寫了三篇,得到了一些朋友的肯定,也收到了一些朋友的反對。在前面的三篇中,我一直至力於編碼,很少涉及到理論,因此很多朋友認為我寫的東西很膚淺,毫無亮點,或許我的水平真的很有限,辜負了大家的期待。這個系列已經20多天沒有更新了,一個是因為時間有點點緊,另一個是因為我現在正在全力的搭建一個案例,然而要搭建起一個能盡量涵蓋企業級應用框架方方面面知識的案例並不簡單,但是如果沒有案例就來寫企業級應用框架無異於紙上談兵。目前我的案例框架尚未完成,還有些東西沒有理順,但是我清楚的知道,我要詮釋的是一種怎樣編程思想,所以這一篇我想從理論上跟大家理一理,我這個系列到底是要說些什么。

三層架構已經過時了么

  在我的一些評論里面,有人提出了三層架構已經過時了。對於這一點,我是不贊同的,三層架構做為一種經典的軟件分層思想,是不存在過時之說的。很多人提出了分三層不夠,對於這一點我倒是蠻贊同的,因此,我們在做項目的時候完全可以根據項目的需要在三層架構的思想上面多擴充幾層,形成多層架構,但是萬事均有代價的,層次愈多,程序的性能也就相對愈差一些,編程起來也就愈繁瑣,因為每層次都必須提供相應的實現代碼,因此一個好的架構師,應該對項目的具體分層有個合理的掌控。

  三層架構作為一種分層的思想,它並未提供給我們具體的實現。因此一個基於三層架構思想的框架的好壞,與搭建它的架構師的水平息息相關,如果當你看見一個基於三層架構的框架覺得很失望,那么很顯然,是這個框架的實現者讓您失望了,而並非三層架構的分層思想讓你失望了。三層架構做為微軟力推的一種軟件分層思想,肯定是具有他的存在價值的,而我目前的案例框架也是從三層架構的思想上擴展而來的,其本質還是屬於三層架構,只是多分了一個服務層而已,這就好比人家問你MVC是不是asp.net, EF是不是Ado.net,你說不是,那樣是會鬧笑話的,因為無論是MVC,還是EF都是在后者的基礎上做了一些擴張與封裝,然后另起一個名字罷了,微軟就喜歡做一些這樣的事情來唬弄.net程序,把大伙搞的傻傻的,以體現它的高大上.......

我要詮釋的三層架構思想

   UI層:這個層我不想多說,因為已經有了一些相應的成熟的技術思想,如果你采用WPF,siverlight技術,那么MVVM編程模式肯定會是你得不二的選擇;當然你說你不喜歡這些插件類型的前端技術,你喜歡自己寫HTML,CSS,JS,那么很顯然微軟的MVC框架會讓你如魚得水;你要是實在不會MVC,只會用WebFrom的話,也沒關系,盡量采用MVP思想去編寫你的代碼。 說到這里,我想提醒一下大家,不要把架構與框架等同起來,架構是分層的思想,而框架是具體實現,你們看我們平時耳熟能詳的wpf,silverlight,MVC框架,其實也只不過是三層架構里面UI層次的一個實現而已。

    業務邏輯層:很多人對這個層的理解並不深刻,認為只要能夠接收到UI層傳遞過來的請求,一步一步的實現其相關的業務功能(當然期間可能會調用數據訪問層,實現持久化)最后把結果返回給UI層,這樣的一個層面就是業務邏輯層。當然我承認我並不能說這是錯的,目前覺大多數公司的業務邏輯層也是這么設計的,簡單粗暴。這種業務組織方式就是大名鼎鼎的事物腳本方式,是一種面向過程的編程方式,程序中每一個業務對應着一個方法,這樣的方式對於中小型的項目沒啥問題,但是如果項目大了就顯得力不從心了,一個方法中可能包含成百上千的代碼(當然你說你可以拆開成很多小方法),但是一個實實在在的問題擺在這里,那就是程序中到處是這樣的小方法,業務理解起來就特別困難,試想一下當你接手一個項目在理解業務邏輯代碼的時候,方法這里跳那里,該有多么悲劇呀。另一個問題這些方法被寫出來有多少能夠被重用我表示很懷疑。

   基於上面的這些原因,我的案例並不打算采用這種事務腳本的方式,我決定采用面向對象的領域模型來組織我的業務邏輯。說的淺顯一點,就是把我們的業務抽象成一個一個的對象(領域模型),當我們要實現某種業務邏輯的時候,我們只需要調用相關的領域模型的即可。當然采用領域驅動編程,遠不是一言兩語能夠說完的,如果細說的話,又可以寫一個系列了,本文只是淺淺的點出我的業務邏輯層的組織方式,下面我給出一張截圖,雖然里面的代碼我並未實現,但是整體的組織思想會是那個樣子

    

其中mode文件夾存放的就是我們的領域模型了(業務對象),Repositories這個是數據倉儲,在數據訪問層我會詳細講到的,services是領域服務,這是因為很可能一些業務涉及到多個領域模型,封裝在那個領域模型中,都顯得別扭,所以以領域服務的方式提供;而event則是領域模型中的事件了,因為原則上來說領域模型應該是一個純凈的業務實體,不會跟任何的技術相關連,但是有些時候,我們又必須提供一些技術相關的方法,比如在刪除一張訂單的時候我們要向客戶發送郵件通知,這個就涉及到郵件服務了,但是為保證我們領域模型的純潔,我們采用了事件來隔離的郵箱服務,具體的郵件操作是以事件的方式注入到領域模型中去的,好了業務邏輯層我們就告一個段落.....

   數據訪問層:很多人對數據訪問層的職責的理解相對狹隘,認為我們的數據訪問層只要幫助我們實現增刪改查(CRUD)即可,其實數據訪問層遠非我們想象中那么簡單。CRUD是他必須提供的功能,除此之外它還必須幫助業務邏輯層,屏蔽掉具體的數據訪問技術的差異,這就要求它提供統一的數據訪問接口,如果您讀過我前面的三篇文章,相信您對這一方面就不會陌生了。我認為一個優秀的數據訪問層,還應該支持工作單元模式,倉儲模式,並能夠有效的控制並發帶來的各種問題,如果您能夠不借助ORM框架做到這一點,那么恭喜您,您會是一個很好的微軟專家的。就我前面的三篇來說,如果我采用ADO.NET去實現數據訪問層,很顯然,這將是一個浩大的工程,這就基本上要求我重新寫一個類似微軟EF的框架了,很顯然我不具備這樣的實力。下面跟大家着重的說一說工作單元模式,與倉儲模式。

   工作單元模式:其實在EF里面已經為我們實現了,當我們做增刪改查的時候,我們並不是每次都向數據庫提交請求,而是把相應的更改狀態記錄在內存里面,然后點擊提交的時候一次向數據庫寫入,這樣做有什么好處呢?很顯然,第一降低了數據庫訪問次數,提升了性能,第二,所有的操作一次性提交,這樣能很好的支持事務操作。工作單元模式說出來很簡單,借助EF框架也容易實現。但是試想一下,如果讓您親手去實現這個模式,又該怎么去折騰呢?

   倉儲模式:其實這個模式我們經常用到,只是我們沒有注意到罷了。比如我們會為數據庫每一張表去建立一個數據實體以及操作這個實體的一個專門的數據庫訪問類,很顯然這個數據庫訪問類就是一個倉存,如我前面幾篇文章中的數據訪問層中的orderDAL類,但是倉儲真這么簡單么? 在前面我提到了我們的業務邏輯層將采用領域模型來組織業務。既然是領域模型,那肯定是一個一個抽象的業務對象啦,業務對象里面肯定包含數據與行為。例如訂單對應的領域模型中,肯定會包含該訂單的所有訂單明細實體,他的行為中肯定是包含了對訂單明細項的CRUD,那么這個時候,我們的倉儲類要解決就是針對我們的訂單領域模型的CRUD,很顯然這是一個多表操作。我們在倉儲中不僅要實現對訂單表的CRUD,還要幫助其實現模型中對訂單明細的CRUD,或許你認為這個很容易,那么想一想我們如果訂單表中還有客戶呢?很顯然,要實現面向對象的領域模型的數據倉儲,並非想象中那么容易,好在EF也提供了相應的支持,如果要自己去寫一個ADO.net針對領域模型的倉儲,其痛苦可想而知......

   IOC與AOP:顯然,我們必須為我們的業務邏輯層屏蔽掉我們數據訪問層的技術差異。我們在業務邏輯層統一調用的是數據訪問層提供的接口,但是無論什么樣的接口都必須提供實例,在我前面的三篇中,我通過讀取配置文件,采用反射的方法來提供實例。很顯然這不是一種好的方法。我們可以用更簡潔的方法,采用IOC容器來幫助我們創建實例,如spring.net,其實目的和我前三篇講的都一樣,就是解除業務邏輯層對數據訪問層的依賴。但是我現在想,在我每次調用數據訪問層方法的時候做一些數據驗證操作以及當我數據持久操作出現問題的時候,我想把異常記錄到日志里面。可是我又不想把數據驗證與日志寫在數據訪問層與業務邏輯層的調用方法中,因為每個方法調用都要寫的話,無疑代碼是冗余的。當然你也可以寫個基類來做相應的操作,但是這樣做並不優雅。這個時候我們就需要AOP技術了,AOP容器可以讓我們在對創建的實例的方法屬性等調用之前或者之后做一些邏輯處理,這些邏輯處理是可以很容易在配置文件中注入進去的......

   服務層:這個是我在三層架構的基礎上面增加的一個層次。為什么要有這個層次?很簡單,我們的業務層被封裝成了一個一個的領域模型與領域服務,而我們的具體業務很顯然必須調用相關領域模型與領域服務來實現,所以服務層要解決的主要問題就是調用各個領域模型與領域服務來實現我們的業務,要調用領域模型則必須能夠創建領域模型的實例,很顯然這項工作得交給數據訪問層的領域倉儲來實現,所以服務層必須添加對數據訪問層和業務邏輯層的引用,它將協調整個領域模型與領域服務來完成業務。另外服務層還必須解決一個問題,那就是DTO領域模型的相互轉化。我們的數據倉儲操作的都是領域模型,而UI層並不關心我們的領域模型,它傳過來的數據或者希望得到的展示數據往往很簡單,這就要求我們的服務層能靈活的進行DTO與領域模型的轉化,有一個第三方框架Automapper在這里推薦一下。

  分布式服務:在我的案例中,我並不打算讓UI層直接引用我的服務層,直接調用我們的相關業務。我打算采用WCF分布式技術來暴露我們的服務。這樣做好處有兩點,第一,UI層徹底的與服務層解耦,第二,當我們的公司,要把項目轉化為移動APP,我們甚至不需要修改一丁點的代碼,同時我們的業務功能也可以被別的系統靈活的調用,當然這個屬於分布式系統的相關知識了。如果細說有可以寫一個系列了,目前我們公司的所有業務系統采用了分布式部署,等這個系列完了,我很可能會根據公司項目寫一個分布式系統的系列

  總結:本文蜻蜓點水的,粗略的介紹了下我這個系列到底要寫些什么東西,雖然不是什么很高深的東西,但是麻雀雖小,五臟俱全,也基本上涵蓋了我目前所掌握的企業級應用框架,應該學習與注意的知識點。這個系列,說出來很簡單,但是要整合出一個案例,真的很難。二十多天來,我一直埋頭寫相關的案例,但是發現有很多的東西自己也理不順。無論如何這個系列我一定會堅持寫下去的,希望大家能夠支持我,而不是喝倒彩,對大家沒一點幫助的或者沒一點深度的東西,我也沒勇氣擺到博客園來。好了已經很晚了,願園子里面每一個人都能成為大牛。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM