什么叫耦合

一、什么是耦合

  耦合表示模块之间的关联程度,分为强耦合和弱耦合。

二、耦合的例子

  例子1:设想一下有十几个灯泡一同插在灯座上,假如其中有一个灯泡坏掉了,那么需要更换整个灯座设备的话,也就是说十几个灯泡全都要换掉,那么我们称这种情况为强耦合。若其中的一个灯泡坏掉了只需将这个坏掉的灯泡更换掉,那么称这种情况为弱耦合。
  例子2:设想有一个机器人,机器人的眼睛坏掉了,假如需要将整个机器人头部给换掉,那么这种情况称为强耦合。若眼睛坏掉了只需更换眼睛,那么则为弱耦合。

三、耦合强的坏处

  从上面的例子我们可以看出,强耦合的系统或者设备,一旦其中的某个零件或者元件坏掉了,我们就要整个设备一齐更换。如此一来,耗时耗力。

四、代码例子

  假设有A1类、A2类、B类,A1、A2继承于B:

class B {
	public void method() { ... }
}

class A1 extends B {
	...
}
class A2 extends B {
	...
}

  原问题:直接调用
  现在写一个强耦合的情况下的代码。这种直接调用是强耦合的。
  存在问题:如果你的项目中到处都是new A1(),那么当你想要将A1改为A2的时候,你就需要在项目各个角落找到这个语句并作修改,如果你的项目有上百层结构,那么工作量是巨大的。

B b = new A1(); //若将A1() 改为A2(),在上百层级结构的项目中将会很繁琐。
b.mehtod();

  改动一:辅助类
  可以改进为松耦合结构,用一个辅助类,通过辅助类调用。
  存在问题:辅助类仍然紧耦合A1类,若要改成A2类还是需要在辅助类里进行小范围更改(假如辅助类很庞大,改动的地方还是有点多了)。

class B_Helper {
	B b = new A1();
	public void useMethod() { 
		b.method();
	} 
}
B_Helper bHelper = new B_Helper(); //如此一来,若要改动A1(),只需在辅助类这一处改动即可。
bHelper.useMethod();

  通过辅助类我们降低了耦合,我们只需要管理辅助类。在上百层结构的项目中,我们看不到new A1()的语句了,映入眼帘的都是new B_Helper()。如此一来,我们只要改动B_Helper类中的A1类,就可以实现全部的改动。再也不用到处找new A1()啦~
  改动二:spring框架
  转自下面这个网站,这里还不怎么熟悉,先挖个坑,待功力上升后再来填满。

https://www.yiibai.com/spring/spring-loosely-coupled-example.html

  可以将辅助类和spring bean配置文件结合,并在spring bean配置文件中声明所有的Java对象的依赖,然后通过Spring来调用它来实现松耦合。只需要改变 Spring xml 文件使用不同的输出生成器。只修改 Spring xml文件而不需要无码修改,这意味着更少的错误。

五、七种耦合类型

根据耦合性从低到高为非直接耦合数据耦合标记耦合控制耦合外部耦合公共耦合内容耦合

1、内容耦合

B模块直接操纵A模块的数据,此时A模块的数据完全依赖于B模块。
在这里插入图片描述

class A {
    public int numA = 1;
}
class B {
    A a = new A();
    public void method() {
        a.numA++;
    }
}
2、公共耦合

A、B模块共同操作C模块的全局数据结构,导致很难确定哪个模块对C的数据进行了操作。
在这里插入图片描述

class C {
    public static int[] arrayC = { 0 };
}
class B {
    public void method() {
        C.arrayC[0]++; // 这里直接用类名.静态变量名调用
    }
}
class A {
    C c = new C();
    public void method() {
        C.arrayC[0]++;
    }
}
3、外部耦合

A、B模块共同操作C模块的全局简单变量,导致很难确定哪个模块对C的数据进行了操作。与公共耦合的区别就是,一个是全局简单变量,一个是全局数据结构。
在这里插入图片描述

class C {
    public static int numC = 0;
}
class B {
    public void method() {
        C.numC++; // 这里直接用类名.静态变量名调用
    }
}
class A {
    C c = new C();
    public void method() {
        C.numC++;
    }
}
4、控制耦合

A模块向B模块传递控制信号,B模块收到控制信号后进行相应的操作。模块之间传递的不是数据,而是一些标志,开关量等等。
在这里插入图片描述

class A {
    public boolean flagA = true;
}
class B {
    public void method(A a) {
        if (a.flagA) {
            // ...
        }
    }
}
5、标记耦合

A模块传递给B模块某个数据结构的地址
在这里插入图片描述

public class Main1 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        b.method(a.map);
    }
}
class A {
    public Map map = new HashMap();
}
class B {
    public void method(Map map) {

    }
}
6、数据耦合

模块之间通过参数来传递数据
在这里插入图片描述

public class Main1 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        b.methodB(a.methodA());
    }
}
class A {
    public int methodA() {
        return 1;
    }
}
class B {
    int numB = 0;
    public void methodB(int num) {
        numB = num;
    }
}
7、非直接耦合

两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现
在这里插入图片描述
本文参考自

https://segmentfault.com/a/1190000037599526
https://www.yiibai.com/spring/spring-loosely-coupled-example.html

  • 1
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值