一个庞大的系统中,分布着许多子系统,子系统中包含许多包,包中又有数不清的类。自类往上,有数不清的调用关系,一旦两个或多个对象(包括类、包、模块、系统等)之间发生关系(这里我们可以认为是调用或依赖),那么就说对象之间发生耦合。
耦合程度的高低,直接影响系统质量,下面讲一下个人理解。
内容耦合:耦合程度最高,模块1直接读取模块2中的数据。相当于直接修改了对方的逻辑,这是不可忍受的。可以想象,自己刚写好的一个方法,有人直接修改我方法中的内容,导致程序运行异常,这种情况下出错都不好排查。 更糟的情况是多个模块互相影响。
公共耦合:模块1和模块2,都引用同一个静态的全局对象。这种情况要求对全局对象写入和读取的时机拿捏的准确,并且需要多个模块都熟悉全局对象的结构及意义才能执行成功。
外部耦合:和公共耦合相似,只是把全局对象换成了一个全局简单变量。因为变量比对象简单,调用者不用费脑子记着对象中每个参数的意义,所以外部耦合要比公共耦合松散。
控制耦合:模块1调用模块2时,通过传简单变量来控制对方的逻辑。这就要求模块1熟悉模块2的内部逻辑,否则他不会知道变量传什么。因此,建议使用见名知意的名字或者Enumeration。
标记耦合:模块之间通过传递对象调用,这种情况比较常见。需要双方都了解对象的结构及字段含义。
数据耦合:模块之间直接传简单参数,这种方式最直接,只要变量名恰当,几乎不用api文档都能调用成功。
非直接耦合:模块之间没有直接联系,通过总线调用互相通信。彼此都感知不到对方的存在,这种耦合最松散。现在比较常见的dubbo、soa都是这个类型。
加深印象:
内容耦合,相当于两个人不分彼此了,你的就是我的,需要什么直接到你家拿,都不用告诉你。(你媳妇天天跟你打仗)
公共耦合:发工资了,两个人的钱打到一个账户上,两人只要知道银行卡号和密码就能花钱了。
外部耦合:又发工资了,这回直接给现金,两人直接拿现金花钱,都不用知道银行卡信息,花钱越来越方便了。
控制耦合:这种调用还得知道对方的处理细节以及控制变量的含义才能调用成功。也就是侵入了对方的逻辑,相当于封装被破坏了。
标记耦合:这已经是能接受的了,但是还是要求双方了解传参对象的含义以及字段的意义,还是得走个脑子。
数据耦合:模块直接调用最简单的方式,见名知意的变量名,简短的参数列表(如果过长还是建议使用标记耦合)。
非直接耦合:由控制中心调用,模块之间都感知不到对方,甚至一个模块偷偷升级了他也不知道,这种情况最自由。
总结:耦合程度的高低实际上就是彼此感知度的强弱,彼此需要了解的越深,表示耦合度越高,如果两个模块都不认识,表示耦合度低。可以想象,如果我要调用一个API,它让我传递五六个参数和一个对象,这个对象包含十几个参数,其中还包括控制流变量,再加上几个全局变量,状态变量,基本上就可以放弃这个API了。相反,如果它只需要三两个int或者String就能调用,我就能把更多的精力放到业务上。说到底,耦合松散的意义就是释放我们的精力,有更多的精力就可以抽象更复杂的问题,做更好的解决方案。