4.2 耦合

耦合

模块之间的交互程度

模块之间的耦合度越弱越好,越强越差

耦合的五种分类或等级

image-20210428154020570

1.内容耦合
2.公共耦合
3.控制耦合
4.印记耦合
5.数据耦合

1、内容耦合

如果一个模块直接引用另一个模块的内容,那么两个模块就是内容耦合的。

内容耦合的缺点:

image-20210428154626958

图中代码示例:在Order类的内部中,实例化Product类,直接通过myProduct实例访问该实例内部的字段,那么这两个类就构成了内容耦合。

内容耦合很危险,因为一个类内部的内容被另一个模块所控制,所以这是我们应该避免的。

2、公共耦合

如果两个模块对全局数据具有写入访问权限,则它们是公共耦合的。

image-20210428155319417

公共耦合的缺点:

  • 与结构化编程的精神相违背

  • 由此产生的代码几乎是不可读的

image-20210428155519709

image-20210428155641682

对于公共耦合的态度,如果实在不能避免,那就尽量减少公共耦合。

3、控制耦合

如果一个模块向另一个模块传递控制元素,那么两个模块就是控制耦合。

例子:

作为参数传递的控制开关

控制耦合的缺点:

  • 模块不是独立的;模块b(被调用模块)必须知道模块a(调用模块)的内部结构和逻辑。

  • 影响可重用性

  • 控制耦合导致被调用模块的逻辑性内聚

image-20210428160453879

示例:模块A调用模块B,模块B具有逻辑性内聚,它做两件事情,一个是就算平均值,一个是取最高值,模块B做哪一件事情决定于模块A传递给模块B的参数,如果模块A传递的参数的average,那么模块B就知道它应该做的事情的计算平均值,如果模块A传递的是highest,那么模块B就去做取最高值,然后把结果返回给模块A。

解决的办法是:

image-20210428160912441

把逻辑判断从被调用模块B中提升到调用模块A中,然后把模块B拆分成两个模块,使每一个模块执行单一的功能。

模块B被分为B1和B2,分别取做平均值和最高值。

4、印记耦合

有些语言只允许传递简单的变量作为参数

例如:

  • 数量

  • 学生姓名

  • 单价

许多语言还支持数据结构的传递

例如:

  • Record

  • ResultSet

  • HashMap

如果一个数据结构被作为参数来传递,而且被调用模块只对传递的数据中的一部分进行了操作,那这两个模块互相之间就是印记耦合。

印记耦合的缺点:

image-20210428161803061

示例:在类Order中,方法getTotalCost,所传递的参数是Customer类的实例customer,在这个方法内部再去取这个实例的等级,然后再获取customer的折扣点。

事实上,在该方法的内部,真正需要的变量只是customerLevel和customerBonuspoint,很显然,传过来的customer中的很多其他属性和数据都不需要,所以该模块和其并用模块之间就具有了印记耦合。

  • 如果不通读整个模块,就不清楚记录的哪些字段被访问或更改。

  • 难以理解

  • 不太可能重复使用

5、数据耦合

两个模块之间数据耦合,如果所有参数都是同类的数据参数,也就是说,每一个参数,或者是简单的数据结构,或者是简单的数据类型,或者数据结构内部的所有数据都被调用模块所使用。

例如:

  • display time of arrival ( FlightNo )
  • 根据航班号,显示航班抵达的时间
  • computeTotalPrice( UnitPrice, Qty );
  • 根据单价和数量,计算总价
  • get job with highest priority ( JobQueue )
  • 从一个队列中,找出优先级最高的任务

数据耦合的好处在哪里?

  • 内容、公共、控制和印记耦合中存在的问题,数据耦合没有存在这些问题。

  • 易于维护


参考或转载:
https://www.icourse163.org/course/NEU-1001812013

posted @ 2021-04-28 21:00  savagefoo  阅读(930)  评论(0)    收藏  举报