• 不要一开始就从服务层开始,只添加那些逻辑不属于任何领域实体或值对象的服务。
• 利用通用语言、契约式设计(DbC)、自动化测试、CI 和重构,使实现尽可能地与领
域模型紧密结合。
从设计和实现的角度来看,典型的 DDD 框架应该支持以下特征。
• 应该是一个以 POJO(如果你的公司以.Net 为主营,就是 POCO)为基础的架构。
• 应该支持使用 DDD 概念的业务领域模型的设计和实现。
• 应该支持像依赖注入(DI)和面向方向编程(AOP)这些概念的开箱即用。(注:稍
后将在文章中详细解释这些概念)。
• 与单元测试框架整合,比如 JUnit、TestNG、Unitils 等。
• 与其它 Java/Java EE 框架进行良好的集成,比如 JPA、Hibernate、TopLink 等。
示例应用
本文中使用的示例应用是一个住房贷款处理系统,业务用例是批准住房贷款(抵
押)的资金申请。将贷款申请提交给抵押放贷公司的 时候,首先要通过承保过程,
承保人在这一过程中根据客户的收入详情、信用历史记录和其它因素来决定批准
还是拒绝贷款请求。如果贷款申请获得承保组的批准, 就进入贷款审批程序的结
清和融资步骤。
贷款处理系统中的融资模块自动给贷款人支付资金。通常,融资过程从抵押放贷公
司(通常是银行)将贷款包递交给产权公司开始。接着产权公司评估贷款包,并与房
产买卖双方一起确定结清贷款的时间。贷款人和卖方与结算中介在产权公司会面、
签署书面协议,来转移房产产权。
架构
典型的企业应用架构由下面四个概念上的层组成:
• 用户界面(表现层): 负责给用户展示信息,并解释用户命令。
• 应用层:该层协调应用程序的活动。不包括任何业务逻辑,不保存业务对象的状态,
但能保存应用程序任务过程的状态。
• 领域层:这一层包括业务领域的信息。业务对象的状态在这里保存。业务对象的持久
化和它们的状态可能会委托给基础设施层。
• 基础设施层:对其它层来说,这一层是一个支持性的库。它提供层之间的信息传递,
实现业务对象的持久化,包含对用户界面层的支持性库等。
让我们更详细地看一下应用层和领域层。应用层:
• 负责应用中 UI 屏幕之间的导航,以及与其它系统应用层之间的交互。
• 还能对用户输入的数据进行基本(非业务相关)的验证,然后再把数据传到应用的其
它层(更底层)。
• 不包含任何业务、领域相关的逻辑、或数据访问逻辑。
• 没有任何反映商业用例的状态,但却能处理用户会话或任务进展的状态。
领域层:
• 负责业务领域的概念,业务用例和业务规则的相关信息。领域对象封装了业务实体的
状态和行为。贷款处理应用中的业务实体例子有抵押(Mortgage)、房产(Property)
和贷款人(Borrower)。
• 如果用例跨越多个用户请求(比如贷款登记过程包含多个步骤:用户输入贷款详细信
息,系统基于贷款特性返回产品和利率,用户选择特定的产品/利率组合,最后系统会
用这个利率锁定贷款),还可以管理业务用例的状态(会话)。
• 包含服务对象,这些服务对象只包含一个定义好的、不属于任何领域对象的可操作行
为。服务封装了业务领域的状态,而业务领域并不适用于领域对象本身。
• 是商业应用的核心,应该与应用的其它层隔离开来。而且,它不应该依赖于其它层使
用的应用框架(JSP/JSF、Struts、EJB、Hibernate、XMLBeans 等)。