凭啥修改代码的是我?原来这就是耦合!

开发 开发工具 前端
本文将讨论的是架构设计中常见的“反向依赖”的设计,以及对应的优化方案,希望对大伙有所启示。

[[405640]]

 

你有没有遇到过这样的场景?

  • 硬件升级,要换一台高配机器;
  • 网络重新规划,若干服务器要调整机架;
  • 服务器当机,要重新部署恢复服务;

更具体的,如上图:数据库换了一个ip,此时往往连接此数据库的上游需要修改配置重启,如果数据库有很多上游调用方,改配置重启的调用方会很多,每次换ip的成本往往很高,成为大家共性的痛点。

由A的调整(数据库换ip),配合修改和调整的却是BCDE(改配置重启),BCDE内心非常的郁闷:明明换ip的是你,凭什么配合重启的却是我?

根本上,这是一个“架构耦合”的问题,是一个架构设计上“反向依赖”的问题,本文将讨论的是架构设计中常见的“反向依赖”的设计,以及对应的优化方案,希望对大伙有所启示。

如何寻找不合理的“反向依赖”耦合?

方法论:变动方是A,配合方却是BCDE。

(或者说需求方是A,改动方却是BCDE。)

画外音:想想“换IP的是你,配合重启的却是我”更好记忆。

如果系统中经常出现了这类情况,就是“反向依赖”的特征,往往架构上有优化的空间。

场景1:公共库导致耦合。

三个服务s1/s2/s3,通过一个公共的库biz.jar来实现一段业务逻辑,s1/s2/s3其实间接通过biz.jar耦合在了一起,一个业务s1修改一块公共的代码,导致影响其他业务s2/s3,架构上是不合理的。

优化方案1:业务垂直拆分。

如果biz.jar中实现的逻辑“业务特性”很强,可以拆分为biz1.jar/biz2.jar/biz3.jar,来对s1/s2/s3进行解耦。这样的话,任何业务的改动,影响范围只是自己,不会影响其他人。

优化方案2:服务化。

如果biz.jar中实现的逻辑“业务共性”很强,可以将biz.jar优化为biz.service服务,来对s1/s2/s3进行解耦。服务化之后,兼容性能更好的通过接口自动化回归测试来保证。

 

基础服务的抽象,本身是一种共性聚焦,是系统解耦常见的方案。

场景2:服务化不彻底导致耦合。

服务化是解决“业务共性”组件库导致系统耦合的常见方案之一,但如果服务化不彻底,service本身也容易成为业务耦合点。

典型的服务化不彻底导致的业务耦合的特征是,共性服务中,包含大量“根据不同业务,执行不同个性分支”的代码。

  1. switch (biz-type) 
  2. case biz-1 : exec1 
  3. case biz-2 : exec2 
  4. case biz-3 : exec3 
  5. … 

在这种架构下,biz-1/biz-2/biz-3有个性的业务需求,可能导致修改代码的是共性的biz-service,使其成为研发瓶颈,架构上也是不合理的。

优化方案:业务特性代码上浮,业务共性代码下沉,彻底解耦。

把swithc case中业务特性代码放到业务层实现,这样biz-1/biz-2/biz-3有个性的业务需求,升级的是自己的业务系统。

场景3:notify的不合理实现导致的耦合。

究竟什么时候该使用MQ?》一文中有一类业务场景,消息发送方不关注消息接收方的执行结果,如果采用调用的方式来实现通知,会导消息发送方和消息接收方耦合。

如何新增消息接收方biz-4,会发现修改代码的是消息发送方,新增一个对biz-4的调用,极不合理。

优化方案:通过MQ实现解耦。

消息发送方upper将消息发布给MQ,消息接收方从MQ去订阅,任何新增对消息的消费,upper都不需要修改代码。

场景4:配置中的ip导致上下游耦合。

即“缘起”中举的例子,下游服务换ip,可能导致多个服务调用方修改配置重启。上下游间接的通过ip这个配置耦合在了一起,架构不合理。

优化方案:通过内网域名而不是ip来进行下游连接。

如果在配置中使用内网域名来进行下游连接,当下游服务或者数据库更换ip时,只需要运维层面将内网域名指向新的ip,然后统一切断原有旧的连接,连接就能够自动切换到新的ip上来。这个过程不需要所有上游配合,非常帅气,强烈推荐!

总结

如何发现系统架构中不合理的“反向依赖”设计?

  • 变动方是A,配合方却是BCDE;
  • 需求方是A,改动方却是BCDE;此时往往架构上可以进行解耦优化。

常见反向依赖如何优化?

(1)公共库导致耦合。

  • 优化一:如果公共库是业务特性代码,进行公共库垂直拆分。
  • 优化二:如果公共库是业务共性代码,进行服务化下沉抽象。

(2)服务化不彻底导致耦合。

  • 特征:服务中包含大量“根据不同业务,执行不同个性分支”的代码。
  • 优化方案:个性代码放到业务层实现,将服务化更彻底更纯粹。

(3)notify的不合理实现导致的耦合。

  • 特征:调用方不关注执行结果,以调用的方式去实现通知,新增订阅者,修改代码的是发布者。
  • 优化方案:通过MQ解耦。

(4)配置中的ip导致上下游耦合。

  • 特征:多个上游需要修改配置重启。
  • 优化方案:使用内网域名替代内网ip,通过“修改DNS指向,统一切断旧连接”的方式来上游无感切换。

【本文为51CTO专栏作者“58沈剑”原创稿件,转载请联系原作者】

戳这里,看该作者更多好文

 

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2021-09-03 10:44:42

ThreadLocalObject 数组

2017-04-24 09:11:22

IP架构数据库

2014-01-02 14:04:42

2016-01-12 17:01:45

Bootstrap原因

2018-01-05 12:39:23

网吧电脑故障

2018-01-02 14:40:58

程序员年龄时间

2015-09-19 13:45:27

2018-11-08 15:30:04

JavaScriptES6异步

2016-11-04 21:42:55

2015-07-21 10:24:02

Windows RT升级

2013-08-30 10:58:59

微信易信

2015-06-30 08:59:28

Web前端程序员

2019-01-02 04:40:19

物联网企业IOT

2020-11-24 06:17:57

微信代码移动应用

2015-07-27 10:56:02

2020-02-17 15:55:22

Office 365

2018-11-01 13:38:51

Java中断停止

2020-07-17 19:31:19

PythonR编程

2015-01-09 10:10:00

Linux

2022-11-21 16:10:31

奔驰可靠性排名
点赞
收藏

51CTO技术栈公众号