前面通过实例解说了一个一环扣一环的面向对象的开发流程:用例模型 -> 领域模型 -> 设计模型(类模型 + 动态模型),解答了面向对象怎样做的问题。接下来我们就要讲“怎样做好面向对象设计”的技巧了

===================================================================

【内聚】

參考维基百科的解释,内聚的含义例如以下:

cohesion refers to the degree to which the elements of a module belong together.

(http://en.wikipedia.org/wiki/Cohesion_(computer_science))

翻译一下即:内聚指一个模块内部元素彼此结合的紧密程度

看起来非常好理解,但深入思考一下,事实上没有那么简单。

首先:“模块”怎样理解?

你一定会说,“模块”当然就是我们所说的系统里的“XX模块”了,比如一个ERP系统的“权限”模块,一个电子商务的“支付”模块,一个论坛站点的“用户管理”模块。。。。。。等等

你说的没错,但在面向对象领域,谈到“内聚”的时候,模块的概念远远不止我们通常所理解的“系统内的某个模块”这个范围,而是可大可小,大到一个子系统,小到一个函数,你都能够理解为内聚里所说的“模块”。

所以,你能够用“内聚”来推断一个函数设计是否合理,一个类设计是否合理,一个接口设计是否合理,一个包设计是否合理,一个模块/子系统设计是否合理。

其次:“元素”到底是什么?

有了前面对“模块”的深入研究后,元素的含义就比較easy明白了(不同语言稍有不同)。

函数:函数的元素就是“代码”

类/接口:类的元素是“函数、属性”

包:包的元素是“类、接口、全局数据”等

模块:模块的元素是“包、命名空间”等

再次:“结合”是什么?

英文的原文是“belong”,有“属于”的意思,翻译成中文“结合”,更加贴近中文的理解。但“结合”本身这个词easy引起误解。绝大部分人看到“结合”这个单词,想到的肯定是“你中有我、我中有你”这种含义,甚至可能会联想到“美女和帅哥”的结合,抑或“青蛙王子和公主”的结合这种情况。

这种理解本身也并没有错,但比較狭隘。

我们以类的设计为例:假如一个类里面的函数都是仅仅依赖本类其他函数(当然不能循环调用啦),那内聚性肯定是最好的,由于“结合”得非常紧密。

但假设这个类的函数并不依赖本类的函数呢?我们就一定能说这个类的内聚性不好么?

事实上也不尽然,最常见的就是CRUD操作类,这几个函数相互之间没有不论什么结合关系(某些设计可能会先查询再改动,但这种设计不是事务安全的),但事实上这几个函数的内聚性非常高。

所以,关于内聚的结合概念,我觉得不是非常恰当的描写叙述。那么,就到底什么才是真正的“内聚”呢?

答案就藏在显而易见的地方,翻开你的词典,细致看看cohesion的含义,你会看到另外一个解释:凝聚力!

“凝聚力”就是“内聚”的核心思想,抛开面向对象不谈,我们日常工作中差点儿随处可见“凝聚力”:

你可能会说,你的团队非常有凝聚力。。。。。。

领导可能会说:我们要增强团队的凝聚力。。。。。。

成功学大师会说:凝聚力是一个团队成功的基石。。。。。。。

面向对象领域的“凝聚力”,和团队的“凝聚力”是一样的概念。

l 推断团队凝聚力时,我们关注团队成员是否都专注于团队的目标;推断面向对象模块的凝聚力时,我们相同关注元素是否专注于模块的目标,即:模块本身的职责!

l 推断团队凝聚力时,我们还会关注团队成员之间是否互相吸引和帮助;推断面向对象模块凝聚力时,我们相同关注元素间的结合关系;

尽管推断内聚性的时候我们会考虑元素的结合情况,但事实上是否专注模块的职责,才是内聚性的充要条件

当模块的元素所有都专注于模块的职责的时候,即使元素间的结合不是非常紧密,也是符合内聚性的要求的,这也是CRUD设计符合内聚性的原因。

所以,推断一个模块(函数、类、包、子系统)“内聚性”的高低,最重要的是关注模块的元素是否都忠于模块的职责,简单来说就是“不要挂羊头卖狗肉”。

【耦合】

參考维基百科,耦合的定义例如以下:

coupling or dependency is the degree to which each program module relies on each one of the other modules

(http://en.wikipedia.org/wiki/Coupling_(computer_science))

简单翻译一下:耦合(或者称依赖)是程序模块相互之间的依赖程度。

从定义来看,耦合和内聚是相反的:内聚关注模块内部的元素结合程度,耦合关注模块之间的依赖程度。

理解耦合的关键有两点:什么是模块,什么是依赖。

什么是模块?

模块和内聚里面提到的模块一样,耦合中的模块事实上也是可大可小。常见的模块有:函数、类、包、子模块、子系统等

什么是依赖?

依赖这个词非常好理解,通俗的讲就是某个模块用到了另外一个模块的一些元素。

比如:A类使用了B类作为參数,A类的函数中使用了B类来完毕某些功能。。。。。。等等

================================================ 
转载请注明出处:http://blog.csdn.net/yunhua_lee/article/details/24481189
================================================

连载:面向对象葵花宝典:思想、技巧与实践(28) - 设计原则:内聚&耦合的更多相关文章

  1. java 28 - 1 设计模式 之 面向对象思想设计原则和模版设计模式概述

    在之前的java 23 中,了解过设计模式的单例模式和工厂模式.在这里,介绍下设计模式 面向对象思想设计原则 在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设 ...

  2. IT第二十天 - 面向对象编程思想、抽象类、异常处理、程序操作日志记录、本周总结 ★★★

    IT第二十天 上午 面向对象编程思想 1.组装电脑的设计: (1)电脑的组成:显示器+机箱 (2)机箱的组成:电源+主板+硬盘 (3)主板所包含的部件:cpu+内存+PCI接口+usb接口 (4)PC ...

  3. 连载:面向对象葵花宝典:思想、技巧与实践(34) - DIP原则

    DIP,dependency inversion principle,中文翻译为"依赖倒置原则". DIP是大名鼎鼎的Martin大师提出来的.他在1996 5月的C++ Repo ...

  4. 连载:面向对象葵花宝典:思想、技巧与实践(32) - LSP原则

    LSP是唯一一个以人名命名的设计原则,并且作者还是一个"女博士"  ======================================================== ...

  5. 连载:面向对象葵花宝典:思想、技巧与实践(35) - NOP原则

    NOP.No Overdesign Priciple.不要过度设计原则. 这应该是你第一次看到这个原则.而且你也不用上网查了,由于这个不是大师们创造的,而是我创造的:) 之所以提出这个原则,是我自己吃 ...

  6. 连载:面向对象葵花宝典:思想、技巧与实践(30) - SRP原则

    前面具体阐述了"高内聚低耦合"的整体设计原则.但怎样让设计满足这个原则,并非一件简单的事情.幸好各位前辈和大牛已经帮我们归纳总结出来了,这就是"设计原则"和&q ...

  7. 黑马程序员——OC语言基础语法 面向对象的思想

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结)(一)基础语法 1)关键字 @interface.@implementati ...

  8. Java面向对象的思想

    面向对象的思想 1.面向对象的思想的特点: ①符合人们的日常思考习惯 ②能将复杂的问题简单化 ③将原来的执行者变为了现在的指挥者 面向对象的思想,所谓的对象,其实就是实体.对于实物的描述,通常有两个方 ...

  9. 面向对象编程思想(OOP)

    本文我将从面向对象编程思想是如何解决软件开发中各种疑难问题的角度,来讲述我们面向对象编程思想的理解,梳理面向对象四大基本特性.七大设计原则和23种设计模式之间的关系. 软件开发中疑难问题: 软件复杂庞 ...

  10. U3D 飞机大战(MVC模式)解析--面向对象编程思想

    在自己研究U3D游戏的时候,看过一些人的简单的游戏开发视频,写的不错,只是个人是java web 开发的人,所以结合着MVC思想,对游戏开发进行了一番考虑. 如果能把游戏更加的思想化,分工化,开发便明 ...

随机推荐

  1. 用C语言怎么实现复制自己

    #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char str[80]; ...

  2. android 逆向project smail 语法学习

    众所周知,android 是开源的.如今市场上反编译别人的劳动果实的人也不少.所以我们也是有必要学习下smail语言,(就是androidproject反编译后出的语法语音),看看改怎么给我们的代码 ...

  3. 基于visual Studio2013解决面试题之0901奇偶站队

     题目

  4. Swift - 添加、修改、删除通讯录联系人

    使用AddressBook.framework框架,我们除了可以很方便的获取通信录里的联系人.同时,还能对通讯录进行新增.修改.删除联系人操作. (注意:这些操作同查询一样,首先需要发起授权请求) 1 ...

  5. Swift - 使用MapKit显示地图,并在地图上做标记

    通过使用MapKit可以将地图嵌入到视图中,MapKit框架除了可以显示地图,还支持在地图上做标记. 1,通过mapType属性,可以设置地图的显示类型 MKMapType.Standard :标准地 ...

  6. [置顶] 手把手教你iOS消息推送证书生成以及Push消息

    iOS推送消息是许多iOS应用都具备的功能,今天在给应用加推送功能,在生成证书的过程中,发生了各种令人蛋痛的事.下面就把步骤拿出来分享下: iOS消息推送的工作机制可以简单的用下图来概括: Provi ...

  7. asp.net 检查文件夹和文件是否存在

    原文  asp.net 检查文件夹和文件是否存在 允许 path 参数指定相对或绝对路径信息. 相对路径信息被解释为相对于当前工作目录. 检查该目录是否存在之前,从 path 参数的末尾移除尾随空格. ...

  8. Windows 7如何建立一个FTP的快捷方式

    原来,使用Windows XP的时候,在IE6的地址栏里输入FTP服务器的地址,就可以打开一个资源管理器的界面来管理文件.但是,随着IE的版本的提升或是装了Windows 7,原来的这种方法就不能用了 ...

  9. Swift - 浮点数转换成整数(四舍五入与直接截断)

    1,直接截去小数部分转换成整数 使用强制转换会将浮点部分去除,把整数部分转换为整数. 1 var i = Int(23.50) //23 2,四舍五入转换成整数 lroundf是一个全局函数,作用是将 ...

  10. D7升级时候发现许多System函数和网络函数只有Byte版本的,需要注意

    SetLength 对于字符串,是WideChar的长度GetMem 只针对ByteMove 只针对ByteFillChar 只针对ByteWriteFile(API) 只针对Byte SetSock ...