應用程序框架實戰三十五:服務概述

  上一篇介紹了我對幾種實體的認識,本篇將介紹幾種服務的用法。程序員

  預告一下本系列後續計劃,本篇以後,準備進入實戰演練階段,先介紹如何快速解決CRUD操做,從如何使用PD數據建模到使用CodeSmith生成代碼,先帶你感覺一下,再回過來介紹框架內部元素,以避免你在閱讀時昏昏欲睡。編程

應用服務介紹

  對於一個新的設計元素,能夠先假定不須要它,等到確實認識到它的做用再引入。那麼,應用服務爲咱們帶來了哪些好處呢?後端

應用服務幫助簡化表現層操做

  以MVC爲例,若是沒有應用服務,那麼控制器將直接調用倉儲,設置查詢條件,轉換DTO等。設計模式

  當控制器操做變得複雜,你會想辦法把控制器代碼分離出去。分離控制器代碼的最好方法就是創建對應的應用服務,不要輕易的分離控制器自己,由於這會致使查找視圖變得困難,而且破壞了約定,致使更高的維護成本。架構

應用服務爲表現層提供惟一的API訪問點

  當一個控制器操做變得複雜時,編寫控制器的程序員須要瞭解更多的知識,這些操做是由哪些聚合、領域服務、基礎設施服務等構造元素組裝起來的呢,調用順序如何?框架

  這是表現層應該關心的問題嗎?分佈式

  表現層應該只關心界面展現,這是表現層的基本職責所在,其它職責儘可能轉移到後方。工具

  應用服務將細粒度操做打包爲粗粒度操做,讓編寫表現層的程序員再也不東張西望,他只須要記得一件事:須要訪問任何後端的操做,找應用服務就對了性能

應用服務爲多個表現層減小冗餘代碼

  若是須要多個表現層,好比須要開發一個WPF程序,功能與MVC徹底同樣,這時候,你會發現表現層充斥大量重複代碼。單元測試

  引入應用服務後,表現層代碼更簡潔,冗餘代碼更少,建立多個表現層更加輕鬆。

應用服務集成和裝配領域層與基礎設施層

  爲了保持領域層的純淨,咱們採用依賴倒置原則,領域層只擁有操做接口,具體實現卻在基礎設施層,最終要能運行起來,必須將它們組裝到一塊兒。

  若是沒有應用服務,控制器將須要本身進行裝配,這增長了表現層的負擔,應用服務承接了這項工做,讓表現層專心幹本身的本職工做。

應用服務配合DTO優化遠程調用性能

  當採用了分佈式架構,爲了提高性能,須要儘可能減小遠程調用次數。        

  應用服務在分佈式環境充當了遠程外觀,配合DTO一塊兒解決這個問題。

應用服務與BLL的比較

  對於長時間採用傳統三層架構的朋友,對於應用服務這個構造是無比的親切,初步用起來之後,你發現這個應用服務就是BLL的翻版。

  BLL是傳統三層架構的業務邏輯層,不少人直接用BLL來命名業務邏輯層的服務類,我暫時就用這個稱呼。      

  BLL是業務邏輯放置的場所,BLL將結果保存到Model實體類中,而後將實體類傳遞給其它層。

  應用服務用於協調領域層與基礎設施層的操做,應用服務自己不該該完成複雜的業務邏輯。

  應用服務與BLL的關鍵區別在於,BLL直接完成業務邏輯,而應用服務會將業務邏輯委託給領域實體或領域服務。

  從代碼上看,BLL主要經過操做Model的屬性進行業務邏輯的處理,而應用服務經過調用領域實體或領域服務的方法完成全部業務操做。        

領域服務介紹

  從前面的介紹,你應該已經發現應用服務是有用的,下面再來看看領域服務。

  在最理想的狀況下,全部的業務邏輯都應該高度內聚到聚合中。但對於更復雜的業務,通常都有比較複雜的流程,這些流程上的控制,放入聚合並不合適,由於這些行爲不屬於某個聚合。

  若是把這些行爲放到應用服務中,可能致使應用服務很是複雜,業務邏輯也從領域層脫離出來,使業務邏輯的管理更加困難。

  爲了把業務邏輯從新移回領域層,須要添加一個領域服務。

  如今咱們有了應用服務和領域服務兩個構造元素,那麼,對於一個複雜操做,應該將哪一部分放入應用服務,哪些又放到領域服務呢?

  書上介紹,業務邏輯可分爲領域邏輯和應用邏輯,領域邏輯應該徹底放到領域層,不能泄露到其它層去,而應用邏輯應該放到應用層服務。

  能夠看出,說得至關抽象,哪一種東西算得上領域邏輯,哪一種又是應用邏輯?這個很難精確劃分。

  一個經典的應用邏輯例子是事務控制,事務控制不是客戶的需求,但卻很是重要,因此把這種東西放到應用層,而不是領域層。

  那麼發郵件的操做是領域邏輯,仍是應用邏輯??有人說是領域邏輯,有人說是應用邏輯,還有人說要看狀況。可謂衆說紛紜,讓你摸不着頭腦。

  不過咱們學習的目的不是進行學術辯論,而是切實的提高項目可維護性,因此不用太理會那些考智商的概念,下面談談個人用法。

  對於應用服務,我老是須要它,由於它能夠簡化表現層開發。

  對於某些比較簡單的業務邏輯,若是發現創建領域服務並未產生太大價值,我就直接放入應用服務中。好比判斷一個實體的名稱不能重複,這是一個業務需求,首先考慮這個業務邏輯能夠放入實體中嗎?不能,由於實體自己沒法瞭解本身的名稱有無重複。其次考慮須要創建領域服務嗎?對於這種簡單業務邏輯,建立一個領域服務有點大炮打蚊子的感受。我會直接將重名檢測放入應用服務中,雖然致使有一點業務邏輯散落到應用層,但我未發現對可維護性形成影響。

  若是業務邏輯比較複雜,我通常會採用TDD方式推動業務開發,這種狀況下,創建領域服務是一個極好的選擇,由於領域層依賴低,單元測試更方便

  不論應用服務,仍是領域服務,開發的基本原則是,儘可能將業務邏輯委託給領域實體,服務僅作調度的工做。

  基礎設施服務比較好理解,就是提供一些基礎支持服務,好比發送郵件等操做。

須要爲服務抽取接口嗎

  學習設計模式時,要求咱們面向接口編程,但一些對象大師建議不要過分設計,以避免致使沒必要要的複雜性,在《實現領域驅動設計》一書中提出,應用服務使用獨立接口沒有什麼好處。

  雖然接口有很多做用,但通常來說,驅動建立接口的真正需求來自多態。在通常的項目開發中,特別是前期,服務不多具備多態需求,那咱們還要不要爲服務創建接口?

  在沒有使用Resharper的年代,我使用接口很是當心謹慎,由於從接口定位實現類很是困難,但自從用上了Resharper,接口再也不成爲障礙。

  另外一方面,IOC框架的使用,讓接口的使用進一步普及,我只須要將實現類綁定到接口,在程序中就能夠自由使用了。雖然IOC能夠直接綁定實現類,但總感受有點奇怪。

  最後,對於跨層訪問,採用接口互聯也符合分層設計原則。

  對於採用了Ioc框架,並安裝了Resharper這樣強大的工具,接口不會給你形成任何不便,至因而否致使複雜性,則須要本身體會。

  代碼中採用接口編程,可能在大多狀況下都未產生實質的好處,但在需求發生變化時,只需修改Ioc配置替換相關實現,這個擴展性在不花成本的狀況下仍是划得來的。

服務命名約定

  當同時須要應用服務和領域服務,會發現服務取名也很困難。好比用戶管理,應用服務叫UserService,若是須要領域服務,也叫UserService就發生衝突 ,但命名爲其它可能又不合適。

  個人辦法是應用服務統一以Service結尾,領域服務統一以Manager結尾,這樣就能夠簡單的解決這個問題。對於和我同樣的英文菜鳥,可能特別有用。

最新源碼發放

  本次更新了EasyUi表格列綁定Combox和Combotree的功能。同時新增了一個圖標管理模塊,該模塊包含對百度WebUploader上傳圖片控件的簡單封裝,服務端上傳操做封裝。

  WebUploader控件很是給力,且提供的Demo很是好用,我基本直接COPY過來簡單修改就用上了。

  我在Data下載包中提供了一些圖標,以方便你們操做。

  同時,該示例包含了領域服務,並提供了相關的單元測試,你們能夠參考。

  下載截幾個運行效果圖。

       

  雖然這個界面包含了樹控件的CRUD操做,但總的JS代碼量仍是比較少的。

 

下載時記得推薦

http://files.cnblogs.com/files/xiadao521/Applications.2015.4.9.2.rar

http://files.cnblogs.com/files/xiadao521/Framework.2015.4.8.1.rar

http://files.cnblogs.com/files/xiadao521/Data.2015.4.8.2.rar        

 

.Net應用程序框架交流QQ羣: 386092459,歡迎有興趣的朋友加入討論。

.Net Easyui開發交流QQ羣(本羣僅限Easyui開發者,非Easyui開發者勿進):157809322

謝謝你們的持續關注,個人博客地址:http://www.cnblogs.com/xiadao521/

相關文章
相關標籤/搜索