赞
踩
转载自:编程道与术
DDD的设计思想
它本身不绑定到任何一种具体的架构风格,可以应用在多种不同的架构风格中。本文探讨在经典的分层架构中如何应用DDD,以及在DDD的语境下,分层结构每一层的具体职责。
分层架构是企业应用开发中采用率非常高的一种架构风格。它将软件系统的不同职责划分到不同的逻辑层中,并严格定义这些逻辑层的调用顺序。
在《领域驱动设计——软件核心复杂性的应对之道》一书中,DDD范式的创始人Evans提出下图所示的这样一种分层架构:
分层架构
整个系统划分为:
基础设施层(Infrastructure)
领域层(Domain)
应用层(Application)
用户接口层(User Interface,也称为表示层)
下面从各个维度分别讨论之。
四个逻辑层之间有着明确的职责划分。
领域层(Domain Layer)
领域层实现业务逻辑
什么是业务逻辑?业务逻辑就是存在于问题域即业务领域中的实体、概念、规则和策略等,与具体的实现技术无关,主要包含下面的内容:
对领域层的进一步说明如下:
应用层定义系统的业务功能,并指挥领域层中的领域对象实现这些功能。
应用层是整个系统的功能外观,封装了领域层的复杂性并隐藏了其内部实现机制。
基础设施层(Infrastructure Layer)
基础设施层为其余各层提供技术支持。
基础设施层是系统中的技术密集部分。它为领域层、应用层的业务服务(例如持久化、消息通信等等)提供具体的技术支持,用户接口层通常使用特定的表示层框架(例如SpringMVC、Struts或Tapestry)实现,但有需要时也可以申请技术设施层提供专门的技术支持。
一些例子:
以上例子都是满足依赖倒置原则,通过控制反转的方式为高层模块提供低层服务,在实践中,可以通过Spring等IoC容器将基础设施层的实现类实例进行依赖注入。
基础设施层的典型实现形式是提供一个一个的类,这些类使用某些专有的技术实现其余各层(主要是领域层)定义的接口,例如提供一个领域层的仓储接口的实现类,使用Hibernate实现持久化,以及提供领域层的通知接口的实现类,使用ActiveMQ广播领域层中发生的事件,等等。
基础设施层也被称为数据源层或数据访问层。这些名称的一个缺点是给读者一个强烈的暗示:基础设施层只负责数据库访问。虽然数据库访问是基础设施层的职责之一,但基础设施层的负责范围比单纯数据库访问宽广的多,它实现了系统的全部技术性需求,例如上面例子中的通知服务和对象序列化服务,等等。
用户接口层为外部用户访问底层系统提供交互界面和数据表示。
用户接口层在底层系统之上封装了一层可访问外壳,为特定类型的外部用户(人或计算机程序)访问底层系统提供访问入口,并将底层系统的状态数据以该类型客户需要的形式呈现给它们。
用户接口层有两个任务:
(1)从用户处接收命令操作,改变底层系统状态;
(2)从用户处接收查询操作,将底层系统状态以合适的形式呈现给用户。
说明:
用户接口层也被称为用户界面层或表示层。
有时候,为了某些需要,我们可以从用户接口层中分离出一个亚层,可命名为门面层(Facade)。位于真正的用户接口层和应用层之间。
门面层隔离前台和后台系统,定义特定于用户接口层的数据结构,从后台获取数据内容并转化为用户接口层的数据形式。
从用户接口层中分离出专门的门面层,具有下面的优势:
用户接口层通过门面层接口与应用层和领域层解耦,意味着用户接口层可以独立开发,不必等待后台系统的完成,亦不受后台系统重构的影响,在需求调研阶段系统原型出来并得到用户确认之后,就可以开始用户接口层的开发了。可以根据界面原型定义用户接口层需要的数据结构,该数据结构与底层数据结构解耦,不需要知道底层数据类型和数据之间的关联关系。将底层数据和界面数据连接起来并相互转换是门面层实现类的职责,这方面工作可以等待前后台系统分别完成之后进行。
如果没有门面层的隔离,用户接口层只能直接使用领域层的领域对象作为自己的数据展现结构。这样我们就不能将系统进行分布式部署,将用户接口层和后台系统(领域层、应用层等)分别部署到不同的服务器上。因为在JPA和Hibernate等技术实现中,领域实体绑定到当前服务器的持久化上下文中,必须脱管之后才能够跨越JVM进行传输。更大的问题是事务问题,事务要跨越服务器的边界,复杂性增加,性能严重下降。门面层的存在使得实体和事务都限制在后台系统,不需要扩展到前台服务器。
在采用JPA或Hibernate作为持久化手段的系统中存在臭名昭著的“会话已关闭”问题,对付这一问题的主要手段是Open Session in View这一存在潜在性能问题的方案。如果不采用门面层隔离后台数据结构,在前端展现数据需要访问实体的延迟初始化属性时就会遇到“会话已关闭”问题,而采用Open Session in View模式处理这个问题就意味着事务不是在后端完成而是扩展到前端用户接口层,在大访问量的网站上会遭遇严重的性能问题并降低吞吐量。采用门面模式的话,有关联关系的数据在后台拼装完毕再一次性返回给前端,事务局限在后端范围,不再有“会话已关闭”和性能问题。
门面层说明
综合说明
各层在运行时对象调用关系如下图所示:
各逻辑层的运行时对象调用关系
各层在编译时的类依赖关系如下图所示:
各逻辑层的编译时类依赖关系
图中infrastructure是基础设施层,domain是领域层,application是应用层,facade和facade-impl是门面层(前者是门面接口层,后者是门面实现层),webapp是用户接口层(采用web形式)。
这里有几个关键点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。