.NET應用框架架構設計實踐 - 概述

作者: dax.net  來源: 博客園  發布時間: 2012-01-19 22:03  閱讀: 4506 次  推薦: 0   原文鏈接   [收藏]  

  我研究領域驅動設計已經近4年時間了,在這4年里,我從了解領域驅動設計的基本思想開始,系統地學習了與領域驅動設計相關的概念、開發模式以及應用系統架構風格,并將其運用在了實際的項目架構與開發中。在此之前,我一直被一些應用程序架構設計上的問題所困擾,比如:在數據持久層,如何讓數據持久化機制能夠支持不同的數據庫類型,甚至是非關系型數據庫;如何能夠讓開發人員將關注點放在領域模型上,而在更改領域模型的同時,不用去關心數據持久化的細節內容;如何將應用程序的視圖模型部署在服務器端,而客戶端可以通過不同的用戶界面代理產生不同的視圖展示機制,等等。為了實現設計思想,我于2008年開發了一套基于類似XUP協議的應用框架原型,在客戶端通過WCF技術與服務器進行通信,以支持服務端事件的響應與處理,而數據訪問部分則采用NHibernate的Schema Tools,在服務每次啟動的時候比對領域模型與數據庫的差異從而動態調整數據庫結構。整個系統的運行機制有點類似ASP.NET,但它可以支持諸如Windows Forms、WPF等多種用戶界面機制(如圖一)。在完成了第一階段的原型開發后,我在《計算機工程與應用》期刊上發表了一篇題為《基于XML的松耦合UI架構的設計與實現》的論文,闡述了這個應用框架的設計與開發的要點與細節。

  遺憾的是,我并沒有真正地完成這個框架的開發。首先,在基礎結構層,使用NHibernate的Schema Tools來完成數據庫的同步過程,會產生很多限制,比如:自動化的數據庫結構變更會出現很多冗余信息,數據庫必須采用關系型數據庫,框架本身需要依賴于一套特定的機制才能實現其功能,ORM具有一定程度的性能損耗,于是應用程序就會產生性能調優的瓶頸;其次,沒有對領域模型的設計與開發做出很好的支持,整個框架更多地是在技術層面為應用程序的開發提供便捷,忽視了領域模型的重要性,這就使得整個框架沒有一個清晰的思路去解決數據映射與傳輸方面的問題;再次,雖然框架已經實現了基于XML的界面描述、事件綁定、事件樁與事件路由等基本特性,但與成熟的框架相比,還是有很大的差距,而彌補這樣的差距還需要花費很大的努力,比如:資源管理系統、基于角色的權限管理系統、商業許可證的授權方式與支持系統、報表管理系統、基于LUA或Javascript的客戶端事件處理系統等等,而這所有的內容都不是光靠我一個人所能完成的。總之,從技術架構上看,除了能夠支持多種用戶界面機制外,整個框架跟ASP.NET很相似。

  然而在設計與實現這個框架原型的過程中,我思考了很多,也學到很多。隨著領域驅動設計思想的引入,我慢慢地在思考:領域模型能否以DTO的形態出現在應用層?倉儲是領域概念,但如果真正將其實現在領域層則明顯不合適,因為它需要與外部技術架構打交道,但如果設計在基礎結構層,由于倉儲是直接對領域對象進行操作的,那么從.NET的開發上來看,基礎結構層的程序集就必須引用領域模型的程序集,于是,領域模型就無法去引用基礎結構層的程序集,因為會產生循環引用,因此也就無法去使用基礎結構層的服務了,像這樣的問題又如何解決?在領域模型中,領域對象能直接操作倉儲來完成業務邏輯嗎?應用層的作用是任務協調,而任務又包含哪些內容?協調又是怎樣的一個過程?應用層與用戶界面層通信是通過數據傳輸對象(Data Transfer Object,DTO)實現的,那么是否需要為每一個領域對象設計一個DTO,如果是的話,那豈不是開發過程會變得非常繁雜,而且會降低應用程序的可維護性,比如今后如果領域模型發生了更改,那么也需要相應地更改DTO。更進一步,是否在領域層與基礎結構層的數據訪問組件之間也需要引入類似DTO的概念,以便解耦領域模型與數據模型?但如果的確如此的話,那系統中豈不是充斥著各種各樣的數據對象?這是基于領域驅動設計的軟件架構的最佳實踐嗎?

  只有真正地實踐,才能很好地回答這些問題。于是,我開始結合ADO.NET Entity Framework來實踐領域驅動的軟件架構,并結合自己的收獲總結了《Entity Framework之領域驅動設計實踐》系列文章,發表在了博客園上。該系列文章獲得了博客園社區讀者的廣泛關注,很多朋友紛紛參與討論,并提出了不少針對性很強的問題,我也盡我自己的最大努力,盡量做到有問必答。于是通過反反復復的討論與相關知識的慢慢積累,一種面向領域驅動的軟件架構設計方式已經在我腦海里成型了,并且在實踐過程中,自己總結了一些“哪些方式是可行的、哪些方法是不合理的”基于領域驅動的軟件架構設計最佳實踐。

  之后,我開始著手把我所總結的這些內容實現在一個應用程序開發框架上,使得軟件人員能夠非常方便快捷地開發出基于領域驅動的軟件架構的應用程序。我將這個框架取名為Apworks(Application Development Framework and Tools的縮寫,取名其實也是來源于我之前提到的那個未完成的框架名稱)。在2009年底到2010年初,我在微軟的開源網站codeplex上簽入了Apworks的第一份代碼,而在2010年底,成功完成了Apworks的Alpha版本,與此同時,Apworks Alpha版的第一個演示案例TinyLibrary CQRS(tlibcqrs)也在codeplex上發布,社區不少朋友對Apworks以及tlibcqrs都非常關注,有朋友甚至希望能夠將Apworks整合到他們的項目中,在此,我對這些朋友們的支持表示衷心感謝。

  基于.NET的框架的設計與開發更不是一件容易的事情,這與“領域驅動設計”相比,它又屬于另一個領域:我們需要考慮的不是通用語言,不是4+1視圖,不是用例,不是角色,不是DCI,不是領域建模;我們需要考慮的是如何搭建一個高效的、穩定的、安全的、可擴展的、基于.NET的應用程序開發框架。而這些,就是本文所要重點討論的內容。

  本文將分為兩大部分,第一部分重點討論基于.NET的框架架構設計的設計指南與最佳實踐,這部分內容都是我在設計與實現Apworks框架的過程中,結合一些理論知識總結出來的,比如如何使用分離接口模式以減小框架本身與第三方組件之間的依賴,如何提高框架的可測試性等;這部分內容還將給出幾個常用的設計模式、體系結構模式和語言慣用法的.NET(C#)實現,以便讀者們在構建自己的應用程序開發框架時,可以在需要的時候直接引用本文給出的模式實現方式,提高開發效率。當然,這些內容都是我的經驗總結,或許會因為我能力有限而出現疏漏或不合理的現象,這就需要讀者朋友們給出意見給予指正了,我也會跟進這些反饋信息而不定期地修訂原文。第二部分將以Apworks為例,詳細講解Apworks框架中某些組件的設計構想,例如,在設計外部事件存儲(Event Store)的時候,我是如何考慮并實現存儲機制的技術無關性的,又比如,“快照提供者(Snapshot Provider)”是如何支持可擴展的基于不同策略的快照功能實現機制,這些內容將在這部分進行討論。

  總之,本文將主要討論基于.NET的應用程序框架架構設計實踐,在此過程中會引用Apworks框架作為案例進行講解,選用Apworks作為案例,首先是因為本文所討論的所有內容都來源于該框架的設計與開發過程中,其次,Apworks已經是一個現成的框架了,讀者朋友在學習的過程中可以有個成品作參考,以便更好地理解本文所討論的內容。希望讀者朋友不會誤認為本文是Apworks的廣告而對之產生反感,我真心希望本文能夠給愛好企業級應用系統架構的朋友帶來一定的參考價值。

0
1
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()