六边形架构设计理论

理论支撑

  • 六边形架构
  • 消费者驱动契约
  • CQRS
  • 模型概念(POJO、DTO、Query、Command、Result、Entity)

文章目录

    • 理论支撑
    • 六边形架构概念
    • 消费者驱动契约
    • CQRS模式
    • 模型概念(POJO、DTO、Query、Command、Result、Entity、Bean)


六边形架构概念

  从分层架构到六边形架构,将系统划分为外层和内层,一个系统包括适配器和应用程序,由各种适配器负责应用程序与外界交互。
  六边形架构还是一种分层架构,如图所示,它被分为了三层:端口适配器、应用层与领域层。而端口又可以分为输入端口和输出端口。
六边形架构设计理论_第1张图片
  六边形架构将系统分为内部(内部六边形)和外部,内部代表了应用的业务逻辑,外部代表应用的驱动逻辑、基础设施或其他应用。内部通过端口和外部系统通信,端口代表了一定协议,以API呈现。一个端口可能对应多个外部系统,不同的外部系统需要使用不同的适配器,适配器负责对协议进行转换。这样就使得应用程序能够以一致的方式被用户、程序、自动化测试、批处理脚本所驱动,并且,可以在与实际运行的设备和数据库相隔离的情况下开发和测试。
  在领域驱动设计(DDD)和微服务架构中都出现了六边形架构的身影,在《实现领域驱动设计》一书中,作者将六边形架构应用到领域驱动设计的实现,六边形的内部代表了application和domain层,而在Chris Richardson对微服务架构模式的定义中,每个微服务使用六边形架构设计,足见六边形架构的重要性。

六边形架构设计理论_第2张图片
传统分层架构的特点:
  传统的分层架构具有广泛的应用,例如经典的三层架构,把系统分为表示层、业务逻辑层、数据访问层。在Martin Fowler的《企业应用架构模式》一书中做过深入阐述,本书04年出版,时至今日分层架构仍然是常用的设计方法,分层架构可以降低耦合、提高复用、分而治之,但同时也还是存在一些问题:
  应用逻辑在不同层泄露,导致替换某一层变得困难、难以对核心逻辑完整测试:你是否有过困惑,代码到底应该放在哪个层,虽然定义了各层的职责,但是总有人不严格遵循层次的分界,对于三层架构,常常会出现业务逻辑写在了表示层,或者业务逻辑直接和数据访问绑定。
  传统的分层架构是一维的结构,有时应用不光是上下的依赖,可能是多维的依赖,这时一维的结构就无法适应了。

六边形架构的特点:
  ① 关注点
  对于分层架构中层次的界定,Martin Fowler给出了一个判定的方法,就是如果把表示层换成其他实现,如果和原来的表示层有重复实现的内容,那么这部分内容就应该放到业务逻辑层。那么如何让开发人员在系统设计过程中始终保持这种视角,传统的分层架构是难以做到的。六边形架构有一个明确的关注点,从一开始就强调把重心放在业务逻辑上,外部的驱动逻辑或被驱动逻辑存在可变性、可替换性,依赖具体技术细节。而业务逻辑相对更加稳定,体现应用的核心价值,需要被详尽的测试。
  ② 外部可替换
  一个端口对应多个适配器,是对一类外部系统的归纳,它体现了对外部的抽象。应用通过端口为外界提供服务,这些端口需要被良好的设计和测试。内部不关心外部如何使用端口,从一开始就要假定外部使用者是可替换的。六边形的六并没有实质意义,只是为了留足够的空间放置端口和适配器,一般端口数不会超过4个。适配器可以分为2类,“主”、“从”适配器,也可称为“驱动者”和“被驱动者”。
  ③ 自动测试
  在六边形架构中,自动化测试和用户具有同等的地位,在实现用户界面的同时就需要考虑自动化测试。它们对应相同的端口。六边形架构不仅让自动化测试这件事情成为设计第一要素,同时自动化测试也保证应用逻辑不会泄露到用户界面,在技术上保证了层次的分界。
  ④ 依赖倒置
  六边形架构必须遵循如下规则:内部相关的代码不能泄露到外部。所谓的泄露是指不能出现内部依赖外部的情况,只能外部依赖内部,这样才能保证外部是可以替换的。对于驱动者适配器,就是外部依赖内部的。但是对于被驱动者适配器,实际是内部依赖外部,这时需要使用依赖倒置,由驱动者适配器将被驱动者适配器注入到应用内部,这时端口的定义在应用内部,但是实现是由适配器实现。

消费者驱动契约

  在微服务架构下,公司的服务由不同的团队提供和维护,在这种情况下,接口的开发和维护可能会带来一些问题,比如服务端调整架构或接口调整而对消费者不透明,导致接口调用失败。
  为解决这些问题,Ian Robinson提出了一个以服务消费者定义契约为驱动的开发模式:“Consumer-Driver Contracts(CDC)”,就是:消费者驱动契约。
  通常我们开发中主要由服务提供方约定接口,虽然提供方架构调整或改变接口之前通常会通知消费者,但可能还存在上述风险,如果上线出现问题就GG了,而CDC则是以消费者提出接口契约,交由服务提供方实现,并以测试用例对契约进行产生约束,所以服务提供方在满足测试用例的情况下可以自行更改接口或架构实现而不影响消费者。
  消费者需要哪些接口、提出接口契约,生产者实现接口;
   消费者(consumer) --> 生产者(producer)

CQRS模式

  CQRS最早来自于Betrand Meyer(Eiffel语言之父,开-闭原则OCP提出者)在 Object-Oriented Software Construction 这本书中提到的一种命令查询分离 (Command Query Separation,CQS) 的概念。其基本思想在于,任何一个对象的方法可以分为两大类:
  命令(Command):不返回任何结果(void),但会改变对象的状态。
  查询(Query):返回结果,但是不会改变对象的状态,对系统没有副作用。
六边形架构设计理论_第3张图片
CQRS模式的特点:
  ① 分工明确,可以负责不同的部分。
  ② 将业务上的命令和查询的职责分离能够提高系统的性能、可扩展性和安全性。并且在系统的演化中能够保持高度的灵活性,能够防止出现CRUD模式中,对查询或者修改中的某一方进行改动,导致另一方出现问题的情况。
  ③ 逻辑清晰,能够看到系统中的那些行为或者操作导致了系统的状态变化。
  ④ 可以从数据驱动(Data-Driven) 转到任务驱动(Task-Driven)以及事件驱动(Event-Driven)。
  ⑤ 方便后期数据治理、数据优化(分库分表、读写分离)。

模型概念(POJO、DTO、Query、Command、Result、Entity、Bean)

  ① Query:
  查询数据相关操作的请求DTO模型,以Query结尾
(返回结果,但是不会改变对象的状态,对系统没有副作用)
  ② Command:
  添加、修改、删除等相关修改数据操作的请求DTO模型,以Command结尾
(不返回任何结果(void),但会改变对象的状态)
  ③ Result:
  所有响应操作相关的DTO模型,以Result结尾
(数据传输对象,Service 或 Manager 向外传输的对象)
  ④ Entity:
  与数据库交互,Mybatis、MybatisPlus、Jpa等,与数据库表名驼峰对应
(对应一个数据库表,其中的属性对应数据库表中的字段)

你可能感兴趣的:(六边形架构,java,项目架构)