我研究领域驱动设计已经近年时间了在这年里我从了解领域驱动设计的基本思想开始系统地学习了与领域驱动设计相关的概念开发模式以及应用系统架构风格并将其运用在了实际的项目架构与开发中
我研究领域驱动设计已经近年时间了在这年里我从了解领域驱动设计的基本思想开始系统地学习了与领域驱动设计相关的概念开发模式以及应用系统架构风格并将其运用在了实际的项目架构与开发中在此之前我一直被一些应用程序架构设计上的问题所困扰比如在数据持久层如何让数据持久化机制能够支持不同的数据库类型甚至是非关系型数据库如何能够让开发人员将关注点放在领域模型上而在更改领域模型的同时不用去关心数据持久化的细节内容如何将应用程序的视图模型部署在服务器端而客户端可以通过不同的用户界面代理产生不同的视图展示机制等等为了实现设计思想我于年开发了一套基于类似XUP协议的应用框架原型在客户端通过WCF技术与服务器进行通信以支持服务端事件的响应与处理而数据访问部分则采用NHibernate的SchemaTools在服务每次启动的时候比对领域模型与数据库的差异从而动态调整数据库结构整个系统的运行机制有点类似ASPNET但它可以支持诸如WindowsFormsWPF等多种用户界面机制(如图一)在完成了第一阶段的原型开发后我在《计算机工程与应用》期刊上发表了一篇题为《基于XML的松耦合UI架构的设计与实现》的论文阐述了这个应用框架的设计与开发的要点与细节
遗憾的是我并没有真正地完成这个框架的开发首先在基础结构层使用NHibernate的SchemaTools来完成数据库的同步过程会产生很多限制比如自动化的数据库结构变更会出现很多冗余信息数据库必须采用关系型数据库框架本身需要依赖于一套特定的机制才能实现其功能ORM具有一定程度的性能损耗于是应用程序就会产生性能调优的瓶颈其次没有对领域模型的设计与开发做出很好的支持整个框架更多地是在技术层面为应用程序的开发提供便捷忽视了领域模型的重要性这就使得整个框架没有一个清晰的思路去解决数据映射与传输方面的问题再次虽然框架已经实现了基于XML的界面描述事件绑定事件桩与事件路由等基本特性但与成熟的框架相比还是有很大的差距而弥补这样的差距还需要花费很大的努力比如资源管理系统基于角色的权限管理系统商业许可证的授权方式与支持系统报表管理系统基于LUA或Javascript的客户端事件处理系统等等而这所有的内容都不是光靠我一个人所能完成的总之从技术架构上看除了能够支持多种用户界面机制外整个框架跟ASPNET很相似
然而在设计与实现这个框架原型的过程中我思考了很多也学到很多随着领域驱动设计思想的引入我慢慢地在思考领域模型能否以DTO的形态出现在应用层?仓储是领域概念但如果真正将其实现在领域层则明显不合适因为它需要与外部技术架构打交道但如果设计在基础结构层由于仓储是直接对领域对象进行操作的那么从NET的开发上来看基础结构层的程序集就必须引用领域模型的程序集于是领域模型就无法去引用基础结构层的程序集因为会产生循环引用因此也就无法去使用基础结构层的服务了像这样的问题又如何解决?在领域模型中领域对象能直接操作仓储来完成业务逻辑吗?应用层的作用是任务协调而任务又包含哪些内容?协调又是怎样的一个过程?应用层与用户界面层通信是通过数据传输对象(DataTransferObjectDTO)实现的那么是否需要为每一个领域对象设计一个DTO如果是的话那岂不是开发过程会变得非常繁杂而且会降低应用程序的可维护性比如今后如果领域模型发生了更改那么也需要相应地更改DTO更进一步是否在领域层与基础结构层的数据访问组件之间也需要引入类似DTO的概念以便解耦领域模型与数据模型?但如果的确如此的话那系统中岂不是充斥着各种各样的数据对象?这是基于领域驱动设计的软件架构的最佳实践吗?
只有真正地实践才能很好地回答这些问题于是我开始结合ADONETEntityFramework来实践领域驱动的软件架构并结合自己的收获总结了《EntityFramework之领域驱动设计实践》系列文章发表在了博客园上该系列文章获得了博客园社区读者的广泛关注很多朋友纷纷参与讨论并提出了不少针对性很强的问题我也尽我自己的最大努力尽量做到有问必答于是通过反反复复的讨论与相关知识的慢慢积累一种面向领域驱动的软件架构设计方式已经在我脑海里成型了并且在实践过程中自己总结了一些哪些方式是可行的哪些方法是不合理的基于领域驱动的软件架构设计最佳实践
之后我开始着手把我所总结的这些内容实现在一个应用程序开发框架上使得软件人员能够非常方便快捷地开发出基于领域驱动的软件架构的应用程序我将这个框架取名为Apworks(ApplicationDevelopmentFrameworkandTools的缩写取名其实也是来源于我之前提到的那个未完成的框架名称)在年底到年初我在微软的开源网站codeplex上签入了Apworks的第一份代码而在年底成功完成了Apworks的Alpha版本与此同时ApworksAlpha版的第一个演示案例TinyLibraryCQRS(tlibcqrs)也在codeplex上发布社区不少朋友对Apworks以及tlibcqrs都非常关注有朋友甚至希望能够将Apworks整合到他们的项目中在此我对这些朋友们的支持表示衷心感谢
基于NET的框架的设计与开发更不是一件容易的事情这与领域驱动设计相比它又属于另一个领域我们需要考虑的不是通用语言不是+视图不是用例不是角色不是DCI不是领域建模我们需要考虑的是如何搭建一个高效的稳定的安全的可扩展的基于NET的应用程序开发框架而这些就是本文所要重点讨论的内容
本文将分为两大部分第一部分重点讨论基于NET的框架架构设计的设计指南与最佳实践这部分内容都是我在设计与实现Apworks框架的过程中结合一些理论知识总结出来的比如如何使用分离接口模式以减小框架本身与第三方组件之间的依赖如何提高框架的可测试性等这部分内容还将给出几个常用的设计模式体系结构模式和语言惯用法的NET(C#)实现以便读者们在构建自己的应用程序开发框架时可以在需要的时候直接引用本文给出的模式实现方式提高开发效率当然这些内容都是我的经验总结或许会因为我能力有限而出现疏漏或不合理的现象这就需要读者朋友们给出意见给予指正了我也会跟进这些反馈信息而不定期地修订原文第二部分将以Apworks为例详细讲解Apworks框架中某些组件的设计构想例如在设计外部事件存储(EventStore)的时候我是如何考虑并实现存储机制的技术无关性的又比如快照提供者(SnapshotProvider)是如何支持可扩展的基于不同策略的快照功能实现机制这些内容将在这部分进行讨论
总之本文将主要讨论基于NET的应用程序框架架构设计实践在此过程中会引用Apworks框架作为案例进行讲解选用Apworks作为案例首先是因为本文所讨论的所有内容都来源于该框架的设计与开发过程中其次Apworks已经是一个现成的框架了读者朋友在学习的过程中可以有个成品作参考以便更好地理解本文所讨论的内容希望读者朋友不会误认为本文是Apworks的广告而对之产生反感我真心希望本文能够给爱好企业级应用系统架构的朋友带来一定的参考价值