1.传统架构常见问题
传统的分层架构具有广泛的应用,例如经典的三层架构,把系统分为表示层、业务逻辑层、数据访问层。
时至今日分层架构仍然是常用的设计方法,分层架构可以降低耦合、提高复用、分而治之,但同时也还是存在一些问题:
- 应用逻辑在不同层泄露,导致替换某一层变得困难、难以对核心逻辑完整测试:
你是否有过困惑,代码到底应该放在哪个层,虽然定义了各层的职责,但是总有人不严格遵循层次的分界,对于三层架构,常常会出现业务逻辑写在了表示层,或者业务逻辑直接和数据访问绑定。 - 传统的分层架构是一维的结构,有时应用不光是上下的依赖,可能是多维的依赖,这时一维的结构就无法适应了。
2.六边形架构特点
架构图
image.png特点
关注点
对于分层架构中层次的界定,Martin Fowler给出了一个判定的方法,就是如果把表示层换成其他实现,如果和原来的表示层有重复实现的内容,那么这部分内容就应该放到业务逻辑层。那么如何让开发人员在系统设计过程中始终保持这种视角,传统的分层架构是难以做到的。六边形架构有一个明确的关注点,从一开始就强调把重心放在业务逻辑上,外部的驱动逻辑或被驱动逻辑存在可变性、可替换性,依赖具体技术细节。而业务逻辑相对更加稳定,体现应用的核心价值,需要被详尽的测试。
外部可替换
一个端口对应多个适配器,是对一类外部系统的归纳,它体现了对外部的抽象。应用通过端口为外界提供服务,这些端口需要被良好的设计和测试。内部不关心外部如何使用端口,从一开始就要假定外部使用者是可替换的。六边形的六并没有实质意义,只是为了留足够的空间放置端口和适配器,一般端口数不会超过4个。适配器可以分为2类,“主”、“从”适配器,也可称为“驱动者”和“被驱动者”。
自动测试
在六边形架构中,自动化测试和用户具有同等的地位,在实现用户界面的同时就需要考虑自动化测试。它们对应相同的端口。六边形架构不仅让自动化测试这件事情成为设计第一要素,同时自动化测试也保证应用逻辑不会泄露到用户界面,在技术上保证了层次的分界。
依赖倒置
六边形架构必须遵循如下规则:内部相关的代码不能泄露到外部。所谓的泄露是指不能出现内部依赖外部的情况,只能外部依赖内部,这样才能保证外部是可以替换的。对于驱动者适配器,就是外部依赖内部的。但是对于被驱动者适配器,实际是内部依赖外部,这时需要使用依赖倒置,由驱动者适配器将被驱动者适配器注入到应用内部,这时端口的定义在应用内部,但是实现是由适配器实现。
代码(模块划分)示例:
GitHup地址: https://github.com/pprector/hexagon
3. 模块讲解
调用流程图:
img2.jpgjava代码模块截图:
image.png模块说明:
hexagon-bootstrap 启动类、配置文件、集成测试
hexagon-facade 外观层, 对外提供所有的接口定义
hexagon-domain 领域层, 处理主要的业务逻辑问题,如果逻辑复杂,可扩展子模块
hexagon-application 应用层,体现对外功能实现. 判断当前功能性质: 执行不同的操作
hexagon-common 工具类,枚举类,异常,跨模块通用对象.
adaptor/hexagon-adaptor-rpc
adaptor/hexagon-adaptor-http
adaptor/hexagon-adaptor-consumer
适配器层: 适配系统各种形式入口,可根据业务场景定制化
infrastructure/hexagon-infrastructure-cache 缓存
infrastructure/hexagon-infrastructure-producer 消息生产
infrastructure/hexagon-infrastructure-repository 数据库
infrastructure/hexagon-infrastructure-rpc rpc
infrastructure/hexagon-infrastructure-task 任务调度
适配器层: 适配组件,可根据业务场景定制化
模块依赖关系
- domain层与facade层不依赖其他层. (common除外)
- application层 依赖 domain,facade. 校验并判断,承上启下
- adaptor层实现facade接口.
- infrastructure 依赖domain,application层 根据业务场景. 定制接口
- bootstrap 依赖所有模块提供启动能力
网友评论