在前面专题一中,我已经介绍了我写这系列文章的初衷了。由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这对于一些刚刚接触领域驱动设计的朋友可能会非常迷茫,从而觉得领域驱动设计很难,很复杂,因为学习中要消化一个整个案例的知识,这样未免很多人消化不了就打退堂鼓,就不继续研究下去了,所以这样也不利于DDD的推广。然而本系列可以说是刚接触领域驱动设计朋友的福音,本系列将结合领域驱动设计的思想来一步步构建一个网上书店,从而让大家学习DDD不再枯燥和可以看到一个DDD案例的形成历程。最后,再DDD案例完成之后,将从中抽取一个领域驱动的框架,从而大家也可以看到一个DDD框架的形成历程,这样就不至于一下子消化一整个框架和案例的知识,而是一步步消化。接下来,该专题将介绍的是:结合领域驱动设计的SOA架构来构建网上书店,本专题中并没有完成网上书店的所有页面和覆盖DDD中的所有内容,而只是一部分,后面的专题将会在本专题的网上书店进行一步步完善,通过一步步引入DDD的内容和重构来完成整个项目。
二、DDD分层架构从概念上说,领域驱动设计架构主要分为四层,分别为:基础设施层、领域层、应用层和表现层。
基础结构层:该层专为其他各层提供各项通用技术框架支持。像一些配置文件处理、缓存处理,事务处理等都可以放在这里。
领域层:简单地说就是业务所涉及的领域对象(包括实体、值对象)、领域服务等。该层就是所谓的领域模型了,领域驱动设计提倡是富领域模型,富领域模型指的是:尽量将业务逻辑放在归属于它的领域对象中。而之前的三层架构中的领域模型都是贫血领域模型,因为在三层中的领域模型只包含业务属性,而不包含任何业务逻辑。本专题的网上书店领域模型目前还没有包含任何业务逻辑,在后期将会完善。
实体可以认为对应于数据库的表,而值对象一般定义在实体类中。
应用层:该层不包含任何领域逻辑,它主要用来对任务进行协调,它构建了表现层和领域层的桥梁。SOA架构就是在该层进行实现的。
表现层:指的是用户界面,例如Asp.net mvc网站,WPF、Winform和控制台等。它主要用来想用户展现内容。
下面用一个图来形象展示DDD的分层架构:
本系列介绍的领域驱动设计实战,则自然少了领域驱动设计分层架构的实现了,上面简单介绍了领域驱动的分层架构,接下来将详细介绍在网上书店中各层是如何去实现的。
三、网上书店领域模型层的实现在应用领域驱动设计的思想来构建一个项目,则第一步就是了解需求,明白项目的业务逻辑,了解清楚业务逻辑后,则把业务逻辑抽象成领域对象,领域对象所放在的位置也就是领域模型层了。该专题介绍的网上书店主要完成了商品所涉及的页面,包括商品首页,单个商品的详细信息等。所以这里涉及的领域实体包括2个,一个是商品类,另外一个就是类别类,因为在商品首页中,需要显示所有商品的类别。在给出领域对象的实现之前,这里需要介绍领域层中所涉及的几个概念。
聚合根:聚合根也是实体,但与实体不同的是,聚合根是由实体和值对象组成的系统边界对象。举个例子来说,例如订单和订单项,根据业务逻辑,我们需要跟踪订单和订单项的状态,所以设计它们都为实体,但只有订单才是聚合根对象,而订单项不是,因为订单项只有在订单中才有意义,意思就是说:用户不能直接看到订单项,而是先查询到订单,然后再看到该订单下的订单项。所以聚合根可以理解为用户直接操作的对象。在这里商品类和类别类都是一个聚合根。
根据面向接口编程原则,我们在领域模型中应该定义一个实体接口和聚合根接口,而因为聚合根也是属于实体,所以聚合根接口继承于实体接口,而商品类和类别类都是聚合根,所以它们都实现聚合根接口。如果像订单项只是实体不是聚合根的类则实现实体接口。有了上面的分析,则领域模型层的实现也就自然出来了,下面是领域对象的具体实现: