解耦与接口-程序员系列第二弹

来源:互联网 发布:网络研修 编辑:程序博客网 时间:2024/05/16 01:32

第一次接触解耦这个概念还是在建筑抗震设计这堂课上。当时不是很懂,只是感到很奇妙,通过引入了一个广义坐标就把多质点体系运动的微分方程组分解成了多个独立的微分方程,然而课后也没有做过多研究。直到最近写了很多代码后,我才对解耦有了更深刻的认识。本文尽量用非专业术语把解耦讲清楚,让大家明白解耦与接口在生活工作中的用途和实现方法。

本文主要探讨以下几个问题

  1. 什么是解耦
  2. 为什么要解耦
  3. 解耦的理论依据
  4. 接口的概念
  5. 如何解耦

在 程序员的第一弹 中,我们谈到了抽象思维。然而理论是丰满的,现实是骨感的。真实世界中的事物大都是相当复杂的,相互之间也有千丝万缕的关系,乍一看无从下手,也理不清头绪,抽象来抽象去发现还是在一圈子里转。这时就要祭出我们的利器–解耦。那么到底是什么解耦呢?为了解释解耦,我们必须先知道耦合。

耦合是指两个或两个以个的体系相互之间产生了依赖关系。

注意,是相互之间产生了依赖。解耦就是为了消除或降低它们之间的耦合性。一个系统的复杂性很大程度上就体现在它的高耦合度,各种约束条件相互关联,正所谓剪不断,理还乱,是“离愁”,别是一番滋味在心头。一旦对其进行了有效地解耦后,就会瞬间觉得如沐春风,一切都变得清晰明了了。腰不酸了,手不疼了,一口气写10行代码,不费劲儿!

为什么会有这种感觉?因为解耦带来了几大好处。

  • 专注于一件事情
  • 便于修改
  • 业务并行
  • 分工协作
  • 通用性强

我们知道,人的大脑在处理一件事情的时候效率是最高的。如果一个问题依赖项太多,复杂度急剧加大,人们往往会顾此失彼。而将问题解耦后,我只需要关心这一件事情,没有过多的外部依赖,处理起来会顺畅很多。

写代码的跟做设计的一样,经常要面临频繁的更改,这对于高耦合体系简直就是噩梦。然而建筑的结构体系就是一个典型的高耦合体系,牵一发而动全身,非常不便于修改,正所谓“建筑两条线,结构一下午”。如果结构体系可以得到充分的解耦,达到一个松耦合的状态,就会出现“建筑十条线,结构两条线”的情况,结构工程师估计睡觉都会笑醒。其实现在如火如荼地进行的装配式建筑、模块化建筑就是解耦思想的具体表现。因为模块之间的耦合性低,相互影响小,模块改动只是内部进行了调整,对外部没有影响。

解耦还有个好处就是可以使工作并行。就像电脑中的多线程,并行处理任务。可以想象,如果任务都是串行的,前一个任务的结果对下一个任务的输入条件有关,一条线走到黑,效率会有多低。同时,这样使分工协作也成为可能,大家互不干扰,开心地做着自己最擅长的事。

最后,也是最重要的一点,低耦合的体系模块必然是一个通用性很强的模块。为什么会这样说,因为耦合性低意味着与其他模块依赖小,那么自身必须是由最基本、最少量的元素组成。而其他复杂的模块最终也是由基本的元素通过复杂的逻辑或运算层层组合得到的,这样使得低耦合的模块可能适配各种复杂的模块,具有很强的通用性。

那么是不是所有的体系都可以解耦呢?大部分人还是持有怀疑态度,因为现实告诉我们,事物关系太复杂,很难理清。但不要着急,我们试着从一个简单的数学小例子来探讨一下。

这里写图片描述

上图表示的是一条直线y=x在坐标系中的位置。为了描述直线上的某一点,我们用一组数(x,y)确定它。换句话说,这个点跟x、y轴产生了耦合。然而坐标系是人为定义的,我们当然可以根据自己的意愿把坐标轴转一个角度,如下图所示,使直线刚好落在x轴上。这样,描述直线上的某一个点,只需要一个x值就能确定了,直观上进行了简单解耦。当然这只是一个很简单的现象,实际上它的本质是矩阵特征值的问题,这里不深究,有兴趣的可以自行研究。想要说明的问题是,我们看待任何一个问题,都是基于自己的“坐标系”。这个“坐标系”不局限于空间位置的描述,而是一种广义的坐标系,跟自己的周围环境、思维习惯以及认知都有关。如果能找一个恰当的角度对问题进行描述,这就使解耦在理论上有了可能性。

这里写图片描述

听起来似乎难以操作,不过聪明的程序员已经摸索出很多套路来实现这些操作。接口(interface)就是应用最广泛的一种。非程序员对接口的概念应该还是停留在生活中具体物体的层面上,比如常见的USB接口、电脑屏幕上的VGA接口甚至是一些电器插头的接口等等。确实,这些接口都是interface的生动具体的展现,但我们不能局限于此。 接口的本质是一种规范,是一种约定。

就像USB接口,我们约定了它的尺寸大小和功能,那么不论你是用于接U盘还是键盘,用来接鼠标还是手机,用来接充电器还是打印机,我都不care,你只要符合约定的接口,都能连接。插上就能用,拔掉电脑也不会死机,本来依赖性很强的关系就被解掉了。

再比如工作中,各专业之间的相互沟通。双方约定了都能听懂的专业术语,这就是接口。我不需要懂你专业的全部知识,我只需要能够识别约定的接口,这样工作内容就可以顺畅交接。专业之间的耦合被解掉。

再比如现在的装配式建筑,连接节点就是接口。两片墙之间约定一种连接方式,只要符合这种接口的规定,墙就可以连接起来。甚至将接口独立出来,墙体只用考虑它模块内的构造,通过接口与其他墙体部件连接。

接口在编程中的应用更是不胜枚举,这里就不一一细谈了。所以对体系进行解耦的有效办法,就是在处理问题时要尽量用接口来描述它与外部的关系。如何找到那个“神秘”的接口呢?这就要回到第一弹去了,对公用的部分进行抽象,提取规范和约定,形成接口。

至此,复杂的问题通过抽象分层被分解,问题之间通过接口被解耦,然后就是专心处理问题内部的事情了。当然,这还没完,往往还需要进行重构与迭代,这是第三弹要讲的内容。欲知详情,请听下回分解。

原创粉丝点击