一、传统分层架构
分层架构的一个重要准则是:每层只能与坐落其下方的层发生耦合。
分层架构分两种:一种是严厉分层架构,规矩某层只能与直接坐落其下方的层发生耦合;另一种是松散分层架构,允许恣意上方层与恣意下方层发生耦合。
下图是一个典型的DDD传统分层架构。
以上分层架构中各层都有自己的职责:
用户接口层负责处理用户请求和用户显示;
应用层完结不同事务场景下的用例或事务流程。其间应用服务一般接纳来自用户接口层的请求,然后经过资源库获取聚合实例,最终履行相应的指令操作,如下示例:
// 应用层的用例
public void cancelOrder(Long orderId) {
Order order = orderRepository.findById(orderId);
// 范畴层的事务逻辑
order.cancel()
orderRepository.save(order);
}
范畴层完结体系的中心事务逻辑,主要包括基于DDD事务建模发生的范畴模型,这儿的事务逻辑不同于应用层中的事务流程,如上代码示例;
基础设施层为其它各层提供通用的技能和基础服务,比如数据耐久化功用。
二、传统分层架构的问题
DDD中资源库(Repository)用来获取或耐久化聚合,每个聚合都拥有一个对应的资源库。由此可见资源库应该和聚合坐落同一层,资源库接口界说应该坐落范畴层,而资源库接口完结需要依靠基础设施层的耐久化机制,此刻资源库接口完结放在哪一层对传统分层架构来说是个问题。
如果把资源库接口完结放在基础设施层,那么基础设施层就会向上依靠范畴层,这样就违反了分层架构的准则:每层只能与坐落其下方的层发生耦合。
或许可以放在范畴层,可是这样会使范畴层依靠数据耐久化的完结细节,导致范畴层不再是一个安稳层。
也可以放在应用层,不过和放在范畴层会有相同的问题。
那有没有更好的方法呢?
有,选用依靠倒置,打破分层架构准则。
三、依靠倒置准则
依靠倒置(或依靠反转)准则(Dependency inversion principle,DIP),由Bob大叔提出,其界说如下:
高层模块不应该依靠于低层模块,两者都应该依靠于笼统。 笼统不应该依靠于细节,细节应该依靠于笼统。
咱们把资源库接口完结放在基础设施层,让基础设施层向上依靠范畴层。尽管这样违背了分层架构准则,可是却符合依靠倒置准则:范畴层(高层模块)不依靠基础设施层(低层模块),两者都依靠于资源库接口(笼统) 。选用了依靠倒置后,一起调整下基础设施层位置,此刻分层架构如下图:
四、六边形架构
分层架构选用依靠倒置准则后,实际上现已不存在分层的概念了。无论是高层还是低层,都只依靠于笼统,好像把整个分层架构给推平了相同。推平后的分层架构如下图:
给推平的分层架构补上左边对称的另一半,其成果就相似六边形架构,如下图是六边形架构。
六边形架构也叫端口和适配器。在这种架构中,针对体系输入输出的不同交互方法,比如http、rpc、mq、数据耐久化等,都有与之对应的适配器,适配器又经过应用层API与内部进行交互。
六边形架构让应用程序可以以共同的方法被用户、程序、自动化测验、批处理脚本所驱动,并且可以让应用程序的鸿沟愈加清晰。有关六边形架构的详细信息可以查看 六边形架构原文翻译
五、为什么不挑选整齐架构?
整齐架构是Bob大叔在其《架构整齐之道》一书中,对六边形架构和其他相似架构做了总结和笼统之后,提出的一种架构规划理念。
书中总结出,六边形架构和其他相似架构规划出来的体系,都具有相同的特点:
独立于结构:这些体系的架构并不依靠某个功用丰富的结构之中的某个函数。结构可以被当成工具来运用,但不需要让体系来适应结构。
可被测验:这些体系的事务逻辑可以脱离UI、数据库、Web服务以及其他的外部元素来进行测验。
独立于UI:这些体系的UI改变起来很简单,不需要修正其他的体系部分。
独立于数据库:咱们可以轻易将这些体系运用的Oracle、SQL Server替换成Mongo、BigTable、CouchDB之类的数据库。因为事务逻辑与数据库之间现已完结了解耦。
独立于任何外部机构:这些体系的事务逻辑并不需要知道任何其他外部接口的存在。
归纳以上所有架构的规划理念,Bob大叔提出了整齐架构规划理念,如下图。
以上图中同心圆别离代表了软件体系的不同层次,一般越接近中心,其所在的软件层次就越高。
整齐架构规矩了层之间的依靠联系规矩:内层(高层)不依靠外层(低层),六边形架构层之间的依靠联系也遵从此规矩。
至此可以以为整齐架构是一种架构规划的指导思想,六边形架构是整齐架构的一种具体的架构规划。
六、总结
选用依靠倒置准则后的分层架构和六边形架构,实际上都符合整齐架构规划理念。可是六边形架构中运用端口与适配器,让应用程序可以以共同的方法被用户、程序、自动化测验、批处理脚本所驱动,一起可以让应用程序鸿沟愈加清晰,从而能更好地防止范畴层和应用层逻辑走漏到外层。
七、参考
- 《完结范畴驱动规划》
- 《架构整齐之道》
作者:京东零售 加文雄
来源:京东云开发者社区