丰富的线上&线下活动,深入探索云世界
做任务,得社区积分和周边
最真实的开发者用云体验
让每位学生受益于普惠算力
让创作激发创新
资深技术专家手把手带教
遇见技术追梦人
技术交流,直击现场
海量开发者使用工具、手册,免费下载
极速、全面、稳定、安全的开源镜像
开发手册、白皮书、案例集等实战精华
为开发者定制的Chrome浏览器插件
从概念上说,领域驱动设计架构主要分为四层,分别为:基础设施层、领域层、应用层和表现层。
实体可以认为对应于数据库的表,而值对象一般定义在实体类中。
下面用一个图来形象展示DDD的分层架构:
本系列介绍的领域驱动设计实战,则自然少了领域驱动设计分层架构的实现了,上面简单介绍了领域驱动的分层架构,接下来将详细介绍在网上书店中各层是如何去实现的。
在应用领域驱动设计的思想来构建一个项目,则第一步就是了解需求,明白项目的业务逻辑,了解清楚业务逻辑后,则把业务逻辑抽象成领域对象,领域对象所放在的位置也就是领域模型层了。该专题介绍的网上书店主要完成了商品所涉及的页面,包括商品首页,单个商品的详细信息等。所以这里涉及的领域实体包括2个,一个是商品类,另外一个就是类别类,因为在商品首页中,需要显示所有商品的类别。在给出领域对象的实现之前,这里需要介绍领域层中所涉及的几个概念。
根据面向接口编程原则,我们在领域模型中应该定义一个实体接口和聚合根接口,而因为聚合根也是属于实体,所以聚合根接口继承于实体接口,而商品类和类别类都是聚合根,所以它们都实现聚合根接口。如果像订单项只是实体不是聚合根的类则实现实体接口。有了上面的分析,则领域模型层的实现也就自然出来了,下面是领域对象的具体实现:
//领域实体接口publicinterfaceIEntity{//当前领域实体的全局唯一标识GuidId{get;}}//聚合根接口,继承于该接口的对象是外部唯一操作的对象publicinterfaceIAggregateRoot:IEntity{}//商品类publicclassProduct:AggregateRoot{publicstringName{get;set;}publicstringDescription{get;set;}publicdecimalUnitPrice{get;set;}publicstringImageUrl{get;set;}publicboolIsNew{get;set;}publicoverridestringToString(){returnName;}}//类别类publicclassCategory:AggregateRoot{publicstringName{get;set;}publicstringDescription{get;set;}publicoverridestringToString(){returnthis.Name;}}另外,领域层除了实现领域对象外,还需要定义仓储接口,而仓储层则是对仓储接口的实现。仓储可以理解为在内存中维护一系列聚合根的集合,而聚合根不可能一直存在于内存中,当它不活动时会被持久化到数据中。而仓储层完成的任务是持久化聚合根对象到数据或从数据库中查询存储的对象来重新创建领域对象。
仓储层有几个需要明确的概念:
//仓储接口publicinterfaceIRepository
定义完仓储接口之后,接下来就是在仓储层实现这些接口,完成领域对象的序列化。首先是产品仓储的实现:
publicsealedclassOnlineStoreDbContext:DbContext{#regionCtorpublicOnlineStoreDbContext():base("OnlineStore"){this.Configuration.AutoDetectChangesEnabled=true;this.Configuration.LazyLoadingEnabled=true;}#endregion#regionPublicPropertiespublicDbSet
publicinterfaceIEntityFrameworkRepositoryContext:IRepositoryContext{#regionPropertiesOnlineStoreDbContextDbContex{get;}#endregion}publicclassEntityFrameworkRepositoryContext:IEntityFrameworkRepositoryContext{//引用我们定义的OnlineStoreDbContext类对象publicOnlineStoreDbContextDbContex{get{returnnewOnlineStoreDbContext();}}}这样,我们的仓储层也就完成了。接下来就是应用层的实现。
应用层应用了面向服务结构进行实现,采用了微软面向服务的实现WCF来完成的。网上书店的整个架构完全遵循着领域驱动设计的分层架构,用户通过UI层(这里实现的是Web页面)来进行操作,然后UI层调用应用层来把服务进行分发,通过调用基础设施层中仓储实现来对领域对象进行持久化和重建。这里应用层主要采用WCF来实现的,其中引用了仓储接口。针对服务而言,首先就需要定义服务契约了,这里我把服务契约的定义单独放在了一个服务契约层,当然你也可以在应用层中创建一个服务契约文件夹。首先就去看看服务契约的定义:
//商品服务契约的定义[ServiceContract(Namespace="")]publicinterfaceIProductService{#regionMethods//获得所有商品的契约方法[OperationContract]IEnumerable
//商品服务的实现publicclassProductServiceImp:IProductService{#regionPrivateFieldsprivatereadonlyIProductRepository_productRepository;privatereadonlyICategoryRepository_categoryRepository;#endregion#regionCtorpublicProductServiceImp(IProductRepositoryproductRepository,ICategoryRepositorycategoryRepository){_categoryRepository=categoryRepository;_productRepository=productRepository;}#endregion#regionIProductServiceMemberspublicIEnumerable
另外,在这里使用了Unity依赖注入容器来对接口进行注入。主要的配置文件如下所示:
最后附上整个解决方案的结构图:
实现完之后,大家是不是都已经迫不及待地想看到网上书店的运行效果呢?下面就为大家来揭晓,目前网上书店主要包括2个页面,一个是商品首页的展示和商品详细信息的展示。首先看下商品首页的样子吧:
图书的详细信息页面:
到这里,本专题的内容就介绍完了,本专题主要介绍面向领域驱动设计的分层架构和面向服务架构。然后结合它们在网上书店中进行实战演练。在后面的专题中我会在该项目中一直进行完善,从而形成一个完整了DDD案例。在接下来的专题会对仓储的实现应用规约模式,在应用之前,我会先写一个专题来介绍规约模式来作为一个准备工作。