耦合关系从强到弱顺序_接口消息导致的组件耦合问题

背景

思考这个问题的时候我翻出了Uncle Bob的clean architecture,我记得这本书里有专门的章节讲组件间依赖程度的度量和管理,希望能有所帮助。结果发现没什么用,这本书里讲的依赖,有点像库和调用库的客户端的依赖,这些不同的块之间可以调用或者引用。这与我想得到的答案不一样。本文这里的组件,指的是部署的独立单元,组件间通过通道进行通信,组件间没有显式的依赖关系,从物理视图方面你可以理解成每个组件都是一个进程。

说清楚问题的边界之后,我们考虑一个问题,怎样的组件设计会导致组件间的耦合?

按理来说,组件间交互只通过通道,组件间的耦合应该是轻微的,甚至是不值一提的。为了理解这个问题的严重程度,我画了一张图。假如只有两个组件:

7456a2f21ed532dca9aeaa10a159b944.png

这是一个典型组件交互视图,主功能流指的是架构最主要需要完成的数据流集合,也是系统最小功能集需要的接口集合,用宽箭头表示。除此之外,A和B之间还有多种顺向消息,多种逆向消息,顺向指的是与主功能流方向相同。

分析

一个消息代表了一个概念在两个组件间进行了维护和抛接,这本身就是一种很危险的信号。两个组件同时维护一个概念必然会带来概念状态不一致、组件间边界争议、故障定位困难、人力浪费严重等问题。从这个意义上,需求应该尽量在一个组件内完成,这应该是一个非常明确的组件划分规则。反过来说,看到一个接口,首先应该问,组件划分是否合理。接口通道的个数,反映了组件间耦合的程度。

有的时候消息抛接无法避免,至少目前已存在的消息80%以上都被认为是无法避免的。那么我们应努力避免同一个概念相关的消息存在多个,这种情况是上一段描述的耦合的进阶版。

有一种接口消息我称之为消息概念环。指的是同一个概念相关的字段,A发给B,B又发给A,这是一种极不稳定的组件设计方法。我们考虑一种情况:组件B因为某些异常情况导致某个消息未成功发送。在消息概念环的设计里,这种情况将导致组件A概念维护异常。状态维护异常对于状态机来说是灾难性的,它将导致组件A无法恢复正常,所以应禁止多组件维护状态机。对于按照现有架构无法避免的消息概念环,应在组件A设计状态回退机制。

有一种接口消息在接收端处理时存在先后关系的绑定。这种绑定关系容易在时序调整、负载平衡等架构变动中产生问题。这种情况如果存在,应该是避免不了的,似乎只能通过某种手段来强化这种先后顺序的管理,如定义一个数组OrderedMsgRcv[MAX_ORDERED_MSG],所有有序消息接收都通过这个数组进行调用。

前面我们提到了应该减少接口消息,那么对于导致概念在全领域蔓延的广播式消息,应该怎么办呢?广播是一种一方提供信息,多方消费信息的方式,其状态维护仍然是统一的。但是由于概念蔓延极容易随着需求的增加而产生环,广播的概念应该引起密切关注。

怎么做

低耦合的组件间设计规则总结如下:

  1. 需求应该尽量在一个组件内完成;
  2. 禁止多组间维护状态机;
  3. 如果无法避免消息概念环,应在状态维护组件设计状态回退机制;

低耦合的接口设计规则总结如下:

  1. 接口消息应尽量少;
  2. 同一个概念尽量不要出现在多个消息中;
  3. 解决消息概念环;
  4. 警惕广播消息;

最后,在讨论接口新增的时候,应该:work together,而不是fight each other。团队壁垒严重,不同团队只看到自己的一亩三分地,看不到整体的人力空耗。在这种情况下,组件边界定义往往是谁不讲理谁有利,这是不对的。接口定义的时候有必要work together,去看看别人的难点,理解对方强调的重点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值