图解面向对象中的聚合与耦合概念

简单理解聚合与耦合

在面向对象的设计中,我们经常会听到或用到聚合、耦合的概念。面向对象的目标就是设计出高聚合、低耦合的程序。然而,究竟什么是 聚合、什么是耦合,恐怕每个人都有自己的答案,换句话说,大多数人对聚合和耦合的概念是模糊的。小弟我今天就在此抛砖引玉,希望能给新入行的朋友和在校的 学生一点帮助。

因为聚合与耦合这两个概念一直都是以"高聚合、低耦合"的形式出现的,刚刚开始接触面向对象设计时,我一直认为聚合和耦合是一对相反的概念,也就是说:只要做到了高聚合,那么自然而然就做到了低耦合。虽然这样的理解并不是错误的,但我并没有思考过原因。

先来看看聚合的定义:聚合(Cohesion)是一个模块内部各成分之间相关联程度的度量。

这里有多个含义值得考虑。首先,聚合是对一个模块内部的度量,这也是许多情况下我们把聚合称之为内聚的原因。第二,这里出现的模块是广义的模 块,它可能是子系统,可能是功能模块,也可能是功能模块中的某一个类。从不同的层次看,聚合的程度也会有所不同。至于为什么不同,后面会有解释。第三,模 块的成分包括模块的行为和状态。要做到高聚合,那么模块内部的行为必须要与模块的内部状态紧密关联。通俗来讲,一个模块仅完成一个独立的功能,模块内部不 存在与该功能无关的操作或状态。

举一个生活中的例子。

有两座城市Sidtown和Fredborough,连接两座城市的公路一天到晚总是拥堵不堪。经过"有关部门"调查之后发现,这两座城市 中有两家公司Better Mousetrap和 Zokko Soda,Better Mousetrap的工厂建造在Sidtown,而该工厂的员工都居住在Fredborough,所以每天早上大批员工从Fredborough出发前往 Sidtown,并在傍晚返回;类似的,Zokko Soda公司的运输车在每天的工作时间都需要在制瓶工厂和灌装工厂穿梭来往。

很明显,如果Better Mousetrap的工厂和员工居住地都在同一城市,而Zokko Soda的两座工厂都建造在另一座城市,那么城市之间的交通状况将会明显改善。

对比两图,上面两座城市间之所以出现交通的问题,是因为每座城市的"聚合性"都比较低:不相关的两个公司出现在了同一座城市,使得城市内部交通的利用率比较低,而城市之间的交通出现了超负荷。

再来看看耦合的定义:耦合(Couping)是模块之间相关联程度的度量。相对于聚合的内向性,耦合关注的是某一模块和其他模块之间的关联 性。其实从前面的例子里,我们已经不可避免的提到了耦合的问题:由于两座城市之间的相互联系过于紧密,导致了城市之间的交通拥堵。另外一个潜在的问题就 是,如果其中一座城市内部的交通出现了问题,另一座城市也会受到影响。我们所追求的低耦合,就是将两个模块之间的关联尽可能的降低,一个模块发生变化对于 其他模块的影响尽可能的小。

再讲一个生活中的例子,相信大部分的80后小的时候都玩过一种掌上游戏机,这种游戏机内含一个俄罗斯方块的游戏。这种游戏机虽然风靡一时,但是不多久就渐渐淡出了市场,因为这种游戏机只有俄罗斯方块可以玩儿,当我们玩儿腻了的时候,这个游戏机也就如同废物一个了。

同期,任天堂推出一款后来风靡了将近20年的红白机,这种游戏机市场寿命如此之长并非游戏机本身质量有多好,而是因为基于红白机开发的游戏 层出不穷,经典无数。魂斗罗、超级玛丽在当时哪怕是现在也是无人不知。红白机的游戏本身并不存储在游戏机当中,每当有新游戏推出的时候,只需要购买新的卡 带即可。正是这种游戏机和卡带相对独立的设计,使得游戏的设计厂商无需关心游戏机的实现细节,只要遵循游戏机提供的接口(插槽)。很多游戏的设计厂商也从 红白机庞大的市场中分得一杯羹。大多数的玩家可能不知道,魂斗罗并非任天堂推出的产品,而是目前以《实况足球》系列闻名世界的KONAMI公司于1988 年从街机移植到红白机上的。

回到耦合的话题上来,因为早先的掌上游戏机将游戏本身内置在机器当中,游戏和机器这两个模块之间的关系过于紧密,所以游戏玩儿腻了,游戏机就 没用了,游戏机出问题了,游戏也再也不能玩儿了。而红白机的游戏和游戏机之间的关系是相对独立的,只要它们都遵循制定好的协议,就可以独立的发展和变化。 游戏卡带摔坏了,其他的游戏一样可以在机器上运行;自己的游戏机坏了,把卡带拿到朋友家的游戏机上也能玩儿。红白机发展到后期,连游戏机的手柄也是可插拔 的,如果手柄坏了,也只需要更换手柄即可。

讲到这里,大家对聚合和耦合应该也有了初步的认识。那么,我们如何看待聚合和耦合在实际当中的应用呢?我们的程序怎样才算是做到了高聚合和低耦合呢?

前面曾经提到,从不同的层次看,聚合和耦合的程度也会有所不同。Sidtown和Fredborough的例子当中,从城市的层次来看,第二 种设计完全达到了高内聚和低耦合的目标,然而,如果从城市的不同区域来看,这样的设计内聚性还不够。如果我们一直追究下去,恐怕Better Mousetrap所有的员工都要住在生产线上了。一味的追求高内聚,必然会造成模块的功能过于单一,而模块的数量出现急剧膨胀。所以,我们在设计和实现 程序时必须要斟酌模块间的聚合和耦合程度,有兴趣的朋友也可以去研究聚合性指标与耦合性指标。

转载于:https://www.cnblogs.com/shsgl/p/3994748.html

图解面向对象中的聚合与耦合概念相关推荐

  1. 面向对象中的聚合与耦合的区别

    面向对象中的聚合与耦合概念 在面向对象的设计中,我们经常会听到或用到聚合.耦合的概念.面向对象的目标就是设计出高聚合.低耦合的程序.然而,究竟什么是聚合.什么是耦合,恐怕每个人都有自己的答案,换句话说 ...

  2. 面向对象IOS编程中的聚合与耦合

    在面向对象的设计中,我们经常会听到或用到聚合.耦合的概念.面向对象的目标就是设计出高聚合.低耦合的程序.然而,究竟什么是聚合.什么是耦合,恐怕每个人都有自己的答案,换句话说,大多数人对聚合和耦合的概念 ...

  3. C++ 深度解析教程(五)进阶面向对象、类与封装的概念、类的真正形态

    十三.进阶面向对象(上) 1.你考虑过吗 日常生活中,我们都习惯于对事物进行分类.那么,这种分类的思想是否可以引入程序设计中呢? 2.面向对象基本概念 面向对象的意义在于 将日常生活中习惯的思维方式引 ...

  4. python的面向对象中属性和方法默认是-Python 面向对象,类的属性和 类的方法...

    面向对象,类的属性和 类的方法 面向对象 类和对象 Python类定义 类属性 类方法 面向过程和面向对象 面向过程 和 面向对象 编程 面向过程 编程:函数式编程,C程序,shell等 面向对象 编 ...

  5. Objective-C向面向对象编程中添加了一个新概念:类别(categor)。

    类别 Objective-C向面向对象编程中添加了一个新概念:类别(categor).类别被设计用于解决这样的问题:基类被认为是很脆弱的,即便是看似无害的改动也不能引入,否则可能会破坏更复杂的派生类. ...

  6. 深入理解领域驱动设计中的聚合

    简介:聚合模式是 DDD 的模式结构中较为难于理解的一个,也是 DDD 学习曲线中的一个关键障碍.合理地设计聚合,能清晰地表述业务一致性,也更容易带来清晰的实现,设计不合理的聚合,甚至在设计中没有聚合 ...

  7. 深入理解DDD中的聚合

    本文来说下领域驱动设计中的聚合 文章目录 概述 聚合解决的核心问题是什么 聚合划分的原则 生命周期一致性 问题域一致性 场景频率一致性 尽量小的聚合 实现方面的考虑 资源库.工厂面向聚合定义 代码结构 ...

  8. 从哲学的角度来看面向对象中的主体客体思维

    01 为什么面向对象难以理解? 面向对象是应用软件设计比较好的方式,可以指导用计算机解决现实中的业务问题,因此是软件开发中的一种主流方式. 不过,用好面向对象则比较困难,即使有数年经验的软件工程师也难 ...

  9. 系统结构设计原则、聚合与耦合

    目录 一.系统结构设计原则 1.分解-协调原则 2.自顶向下的原则 3.信息隐蔽.抽象的原则 4.一致性原则 5.明确性原则 6.模块的扇入系统和扇出系数要合理 7.模块的规模适当 8.考点:系统结构 ...

最新文章

  1. php简单实例,php实现推荐功能的简单实例
  2. Oracle分区表 (二)
  3. concat合并的数组会有顺序么_JS数组 Array
  4. CSS基础(part2)--CSS选择器
  5. Nuget 启用数据库迁移的时候一定要把包含DbContext的项目设为启动项目
  6. amazon alexa_亚马逊使向自定义Alexa Skills添加声音变得更加容易
  7. RTSP协议分析(二)
  8. 配置linux定时任务没跑,Linux配置定时任务
  9. 中set无效是怎么回事_静态时序分析圣经翻译计划——第十章:鲁棒性检查 (中)...
  10. 最新的 iOS 申请证书与发布流程 2016
  11. 【MOOC】JS脚本|便于复制粘贴中国大学MOOC网站的测试题和选项
  12. [魔方]魔方七步初级教程
  13. 小程序为什么有的方法要写在methods,有的可直接写在page下
  14. 智慧医院3D导航导诊系统-基础功能详解
  15. fastadmin后台多表联查
  16. 高度设置php,uedit设置固定高度
  17. 2010年考研英语一阅读A题翻译加解析
  18. Android通话录音流程
  19. linux多线程调试
  20. 基于java springboot android 安卓图书借阅系统源码(毕设)

热门文章

  1. Android面试题详细整理系列(二)
  2. android技巧:apk文件反编译以及签名打包,APKTool 反编译,打包,签名
  3. 二叉树的基本特性和二叉树的几种基本操作的机制_关于二叉树,你该了解这些!...
  4. php将上传的图片转为base64,html5实现把上传的图片转成base64编码在显示(代码实例)...
  5. mysql8 修改密码_最新版本mysql8.0.18windows x64部署手册
  6. 大学计算机软件专业生应该学什么(转)
  7. LOJ #6358 前夕 (组合计数、容斥原理)
  8. jdbc oracle添加数据库连接,JDBC与Oracle数据库连接最常用方法
  9. linux vim配置怎么打开文件,Linux如何设置默认VIM打开文件
  10. 设计模式系列 - 解释器模式