如何减少代码间的相互影响?

在实际的研发工作中,你是不是遇见过以下场景?

  • 一个平台系统,需要接入各种各样的业务系统,而这些业务系统都有自己的账号体系,平台需要兼容这些系统的账号体系,于是代码中出现了大量依赖于各种账号体系的代码。

  • 一个网站页面,需要越来越多的频道(首页、搜索、分类等),不同频道对应的个性化需求各不相同,并且各种页面的标准组件、布局、模板,以及与后端交互框架也各不相同,不同体系的代码依赖非常紧密。

  • 一个通用的订单处理平台,各条业务线都需要通过这个平台来处理自己的交易业务,但是垂直业务线上的个性化需求太多,代码里随处可见定制化的需求代码。

对于这些问题,你可能已经有解决方案了:如果依赖和控制的东西过多了,就需要制定标准,反转控制,解耦,分层……甚至你也知道该如何在代码中解决这些问题,比如,面向接口编程,而不是面向实现编程。

在这个解决过程中,其实你已经在使用 DIP 了,可能对于 DIP 概念本身,还没有透彻理解,甚至说到 DIP 时感觉还很陌生。别担心,今天我就带你一起搞清楚 DIP,让 DIP 在你的开发工作中发挥更大的作用。

下面,我们就一起来看看依赖反转原则(Dependence Inversion Principle,简称 DIP)

一、DIP:统一代码交互的标准

那应该怎么去理解“依赖反转”这个概念呢?其实,对于这种抽象性的概念,我很建议你结合现实生活中的场景或例子来剖析和理解。

比如,在没有电商的时代,商品交易时,通常是买家一手交钱、卖家一手交货,所以基本上卖家和买家必须强耦合(因为必须要见面交易)。而这时有一个中间商想出了一个更好的办法,让银行出面做交易担保——买家把钱先付给银行,银行收到钱后让卖家发货,买家收验货后,银行再把钱打给卖家。通过这样的方式,买卖双方把对对方的直接控制,反转到了让对方来依赖一个标准的交易模型的接口——银行。

这和浏览器的使用原理也很类似。浏览器(对应商品买家)并不依赖于后面的 Web 服务器(对应商品卖家),其只依赖于 HTTP 协议(对应银行),只要我们遵循 HTTP 协议就能在浏览器中提供很多丰富的 Web 功能,而不必针对特定的浏览器定制开发。

因此,我们可以总结一下,依赖反转原则(DIP)就是一种统一代码交互标准的软件设计方法

回到 DIP 的概念上来,我们可以看一下它的原始定义:

  • 高级组件不应依赖于低级组件,两者都应依赖抽象;

  • 抽象不应该依赖实现,实现应该依赖抽象。

那应该如何去理解 DIP 这个原始定义呢?

首先,定义中的高级组件和低级组件,主要对应的是调用关系上的层级。比如,汽车油门(高级组件)调用汽车引擎(低级组件),但并不是说汽车油门就比汽车引擎更复杂、功能更完善、能力更高。再比如,软件程序都得依赖底层操作系统,而你不能说软件程序就一定比操作系统复杂。

其次,高级组件和低级组件都应依赖抽象,是为了消除组件间变化对对方造成的影响,换句话说,抽象是一种约束,让高级组件或低级组件不能太随意地变动。因为两者间有相互依赖关系,一方变化或多或少都会带给对方影响。比如,踩油门是加油,抬起油门是减油,这是一种抽象约束,只要约束不变,我们设计圆形油门还是方形油门都不会影响引擎的动力控制;反过来,引擎使用铝制还是铁制,也不影响引擎对油门加、减油的控制。

最后,抽象不应该依赖实现,实现应该依赖抽象。什么意思呢?这里我们拿 JDBC 这个数据库驱动协议作为例子来简单解释一下。在用 Java 开发增删改查的数据业务时,我们通常会开发一个数据库访问层——DAO 层,而它并不直接依赖于数据库驱动(实现),而是依赖于 JDBC 这个抽象。JDBC 并没有受不同数据库设计的影响,只要不同数据库驱动都实现了 JDBC,就能被 DAO 层所使用,而为了让应用程序使用,数据库驱动也依赖于 JDBC,这便是抽象不应该依赖实现,实现应该依赖抽象。

二、为什么要使用 DIP?

了解了 DIP 的概念及要点后,可能你会疑问为什么要使用 DIP,或者说 DIP 的使用意义有哪些。大致总结为如下两点:

  • 可以有效地控制代码变化的影响范围;

  • 可以使代码具有更强的可读性和可维护性。

使用 DIP 的第一个目的就在于:控制这种代码变化带来的影响

比如,为了解决平台接入权限的问题,我们可以通过抽象一个账号权限体系的接口标准,让不同的业务系统按照这个统一标准来接入平台,同时我们的平台也按照这个标准来实现。此时,我们的内部系统和外部系统不再是通过定制化的映射来通信,而是使用了一套统一的标准接口来通信,只要接口不发生变化,即使外部系统发生了巨大变化,接入的功能并没有发生改变,这样就能有效地控制外部系统的变化对内部系统带来的影响。

使用 DIP 的第二个目的在于,增强代码的可读性和可维护性。该怎么去理解这个目的呢?

虽然现如今软件行业提倡“敏捷开发”,少写文档和注释,需求能提前上线更重要,但是,少写文档不是让我们不写文档和不写注释。比如,你接手两个项目,一个项目不仅没有系统设计文档,还没有代码注释,同时代码逻辑依赖又很多,到处都是看不懂的定制化逻辑;而另一个项目,只有少量文档,并且还有很清晰的接口定义和代码注释。通过这样的对比,你是不是立马就能知道哪个项目的维护难度更低?

使用 DIP,就是从设计上减少系统的耦合性,更能帮助厘清代码逻辑,因为代码是通过统一抽象之后,功能相同的处理都在同一个地方,所以,代码变得更加顺畅,更容易让人理解,也就增强了代码的可读性和可维护性。

三、如何给具体实现抽象标准接口

下面我们通过设计一个 Java 组件来演示其应用思路

这个组件我们只实现一个功能:读取一串字符后,再输出显示。组件中我们定义 StringProcessor 类,该类使用 StringReader 组件获取 String 值,然后使用 StringWriter 组件将值写入输出流并打印。我们将 StringReader 类和 StringWriter 类统称为低级组件,StringProcessor 称为高级组件,这样能更清楚地了解每个设计选择是如何影响整体设计的。

1、设计一:低级组件和高级组件都作为具体类放在同一包中

StringProcessor 取决于 StringReader 和 StringWriter 的实现,读取字符并输出打印,整个逻辑实现在同一个包内通过三个具体类来完成,如下示例代码:

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 答:避免代码耦合的方式包括:1.使用模块化设计;2.使用抽象层和封装;3.使用面向对象编程;4.遵循SOLID原则;5.使用有意义的变量和函数名称;6.使用解耦合的测试方法;7.使用依赖注入;8.使用设计模式。 ### 回答2: 避免代码耦合是一种良好的编程实践,它能够提高代码的可维护性和可读性。以下是一些常见的避免代码耦合的方式: 1. 抽象和封装:将代码按照功能划分成独立的模块,并使用抽象层和接口封装模块内部的具体实现,使模块之的依赖关系降低到最小。 2. 单一职责原则:确保每个类和函数只负责一个单一的功能,避免一个类或函数承担多个职责,这样可以减少代码的相互依赖。 3. 松耦合设计模式:采用设计模式中的松耦合原则,如观察者模式、策略模式等,通过对象的解耦合,减少修改一个对象对其它相关对象造成的影响。 4. 依赖注入:通过依赖注入的方式,将类之的依赖关系从类内部移出,由外部容器来负责类的实例化和依赖对象的注入,降低类之的耦合度。 5. 接口和抽象类:将代码中可变的部分抽象出来,定义接口或抽象类,实现类通过实现或继承这些接口或抽象类来实现功能,通过这种方式可以降低模块之的耦合度。 6. 解耦合的设计原则:遵循开闭原则、迪米特法则等设计原则,减少模块之的依赖,使得模块之的关系更加松散,降低代码耦合度。 总之,避免代码耦合的方式包括抽象和封装、单一职责原则、松耦合设计模式、依赖注入、接口和抽象类及解耦合的设计原则等。通过这些方式,可以提高代码的可维护性和可读性,降低开发和维护的难度。 ### 回答3: 避免代码耦合的方式有以下几种: 1. 使用接口或抽象类:将实现细节与接口或抽象类分离,使得代码对实现细节的依赖降到最低。通过定义接口或抽象类,可以在多个类之定义统一的接口规范,降低类之的耦合程度。 2. 模块化设计:将代码模块化,各个模块之的关系应该是松散的,尽量减少模块之的直接依赖关系。模块之通过接口进行交互,而不是直接依赖具体的实现。 3. 使用事件驱动的编程模型:将代码按照事件进行组织,各个部分之通过事件进行通信,而不是直接引用对方的代码。这样可以减少代码的直接依赖,提高代码的可维护性和可扩展性。 4. 使用依赖注入(Dependency Injection):通过将依赖关系的创建和解决交给第三方容器来管理,从而降低代码的耦合。通过依赖注入,可以将依赖关系从代码中解耦出来,提高代码的可测试性和可维护性。 5. 遵循设计原则:例如单一职责原则、开放封闭原则等,通过良好的设计原则可以减少代码的耦合。 6. 使用设计模式:使用常见的设计模式,如工厂模式、观察者模式等,来解耦代码的依赖关系,提高代码的可复用性和可扩展性。 总之,避免代码耦合的关键是要进行模块化设计,降低模块之的直接依赖关系,并采用合适的设计原则和设计模式来解耦代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱娃哈哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值