0
点赞
收藏
分享

微信扫一扫

对于反向依赖的理解和解决思路

本文将会介绍软件工程中反向依赖的相关概念以及问题解决思路。本文适合那些在为工程中依赖关系复杂或对于工程解耦无从下手的人群。往往上述类别的工程中会出现反向依赖的错误设计,使的开发工作变的很被动,被第三方服务牵着走。希望本篇文章可以为你解决此类问题提供一些想法和思路。
笔者也会将自己的理解在文中进行阐述,这也算是在和大家交流心得的一个过程。若文中有错误的理解和概念,请大家及时纠正;吸纳大家的建议,对于我来说也是很重要的学习过程之一。

1.概念

反向依赖问题的一大特征为:一点改动会引起多处也需要改动。即为根据需求应该只有一处需要更改,而实际上变为因更改这一处而导致其他多处也需要修改的问题。造成这样的现象,一般都是因为在架构设计初期时,功能之间的耦合度过高。

  • 常见的问题设计方式有以下几种:

    1. 工具类包引用过度
      即存在多个工程都在引用同一个依赖包的现象。
    2. 业务逻辑混杂
      有可能出现一个工程中包含着大量的业务逻辑,这些业务逻辑之间的联系往往不是那么紧密。
    3. 同步操作
      同步操作中可能包含了大量操作,但这些操作之间的关系可能并不是需要那么紧密相连。
    4. 硬编码
      最常见的例子就是将配置写死在程序中。

    看到这里,大家也应该能感觉到,反向依赖问题实质上还是一个架构设计的问题。准确来说是一个架构耦合的问题。因此,我们就可以从解决架构耦合度的角度来思考如何解决该问题了。

Tips: 笔者这里想说一点的是,上述的问题现象描述也从侧面体现出了项目初期架构设计的重要性。很多时候,由于业务上的需求紧急会导致我们对于架构设计的时间并不充裕。但笔者强烈建议,即使时间不充裕,我们也应尽最大努力将架构设计的具有可扩展性。时间不充裕的问题,可以通过积攒丰富的设计经验以及总结提炼出通用的架构模型来应对和解决。

2.解决思路

本章节会针对第一章中所提到的几类常见的反向依赖问题来分析以及提出解决思路。希望这些想法能够帮助大家来解决此类问题。

2.1 工具类包引用过度

对于这类情况,可以根据工具类包的内容来分类讨论。

  1. 工具类包为基础功能型
    则可以依据该工具包实现一个基础功能类型的service。例如数据查询服务,数据写入服务等。然后将原本引入工具类包的业务逻辑更改为调用(依赖)相应的service。使得业务逻辑和基础功能逻辑解耦,上层业务不再关心基础功能层的操作细节,只专心负责处理业务;而基础功能层服务之关心如何更高效的完成相应功能,而不用再在其中加入过多的业务逻辑。
  2. 工具类包为业务逻辑型
    这种现象说明,该业务逻辑的公用性很强,即在很多业务场景中都会涉及到。此时,可以依赖于该工具类包创建一个通用业务类型的service。原有业务逻辑中,牵扯涉及到该通用业务的场景更改为直接调用该service。这样就实现了业务逻辑之间的解耦,一是可以将多数业务中重复的逻辑进行抽象和复用;二是可以对业务逻辑进行瘦身,使得原本复杂的业务逻辑变为多个结构清晰的简单业务逻辑。

对于上述解决思路,笔者认为这也是一种分层服务化的体现。通过对经常会使用的到逻进行抽象并实现为通用服务,来实现服务下沉。即将经常复用以及重要的逻辑下沉到架构体系中的基础层中,这样可以使得针对业务逻辑的开发以及针对功能层的开发工作变得直观和高效。开发前者时,只需要关注业务逻辑的细节即可;开发后者时,只需要关注功能稳定和高效即可。同时,还能够解决例如反向依赖这类的问题。

2.2 业务逻辑混杂

对于这类情况的处理,有些类似于上一章节所介绍的服务化下沉。之所以造成这种问题,是因为没有将需求(业务逻辑)拆分细化。通常都是因为工期紧张,从而选择了在已有工程上增加新的业务逻辑来解决需求,然而这些新增的需求却和工程的关系并不大。
此时,可以通过将原有业务逻辑中的每一块子业务逻辑抽象和实现为独立的service来实现业务解耦。原本工程中业务逻辑之间的互相调用更改为调用相应的业务service。在拆分业务逻辑的同时,还可以结合上一章节中所介绍的方法,将通用的业务逻辑进行抽象和下沉。这样就可以将原来的大业务逻辑工程拆分为多个独立自主的业务service和通用业务service以及基础功能service的组合了。
笔者认为,处理这种类型的反向依赖问题最核心的一点就是,要保证服务化的彻底。在了解和分析需求的阶段,应反复询问自己:这些业务需求是不是已经拆分到最细了?哪些业务逻辑出现了多次?等等这样类似的问题。我们可能一次做不到完全的拆分和抽象,但就像笔者在第一章中所说的,我们应尽力而为的将架构设计为合理的。这样才能够为后续的工程维护以及持续开发奠定好基础(当然,如果你说这工程以后不会再更新了,那当我没说~)。

2.3 同步操作

有些时候,为了能够快速实现出相应的功能。大多数人可能会选择将很多操作封装到同一个方法中来实现,即通过同步的方式来编写逻辑。当一个同步操作流程中涉及到的操作过多时,并且流程中流转的数据抽象不得当时,可能就会发生反向依赖的问题。
对于这类情况,可以针对同步操作的流程进行分析:查找流程中有哪些操作是可以通过异步方式实现的?或是哪些操作之间实际上并不关心相互之间的执行结果?在找出有这些特定的操作后,就可以针对它们进行服务化,将原本的同步操作更改为异步调用的方式来实现,从而使得业务流程解耦。
在这里,笔者推荐使用消息队列(MQ)来实现上述思路。因为消息队列的几大特性中就包括工程解耦和异步化,这些特性正好与上述思路的实现点所吻合。可以将原本繁杂、冗余的同步操作逻辑改造为生产消费模型,从而实现工程的异步化。

2.4 硬编码

这种类型的反向依赖问题是大家最容易理解的,同时也是最常见的反向依赖问题。例如,有很多同学会将服务请求的URL或IP直接写死在代码中。这样的做法会带来的问题也是显而易见的了,即如果需要修改这些细节,需要修改相关代码段以及重启服务。
当然,解决这类问题的方法大家应该也想到了。笔者这里推荐使用配置中心来解决该类问题。结合之前章节的介绍得知,通过服务化可以解决大部分类型的反向依赖问题。然而服务化恰巧是微服务中的一个重要的概念,因此可以通过引入微服务中另一个重要的概念: 配置中心来协助解决该问题。配置中心最大的好处就是可以实现动态实时更新配置信息,同时还能将配置管理集中化,使得开发和运维人员能够更便捷的对工程配置进行管理。

举报

相关推荐

0 条评论