原文:
http://socket.blog.163.com/blog/static/209873004201096210555/高内聚,低耦合(High Cohesion、Low Coupling)
是一句近乎于“为实现四个现代化而努力”式的口号,耳熟并不一定能详。这个口号是在软件工程里第一次碰到的,它的定义估计是计算专业术语里最欠扁的定义,内聚:一个模块内各个元素彼此结合的紧密程序。耦合:一个软件结构内不同模块之间互连程序的度量。这两个定义,相当地“形而上学”“不知所云”。这是软件工程中判断设计好坏的标准,主要是面向对象设计,主要是看类的内聚性是否高,偶合度是否低。为什么要高内聚,使模块之间的关系越紧密出错就赵少,越紧密运行效率越高!低耦合,就是说,子程序之间的关系越简单,越容易扩展和维护,越复杂就会产生出更多的意想不到的错误!不利于维护。
程序员天生都是内聚的高手,违反高内聚的反而是那些有一定水平的程序员,可能是误用了设计模式,可能是考虑问题过分全面,把一个功能单一的类分割成多个类。这里重点说低耦合,耦合就是类之间的互相调用关系,如果耦合很强,互相牵扯调用很多,那么会牵一发而动全身,不利于维护和扩展。什么方法、数据、不加分析地往一个类里整,甚至时一个类的所有数据成员设成public,方便在其它类里直接修改数据。生活中很多“低耦合”的例子,如床与床单,如果是紧耦合的话,换床单时,也要换床。再如桌子与抽屉。
图中的上半部分中,把一个软件模块抽象成线条,软件模块互相依赖,这是一种面向过程的开发方式,如果软件是不改变的,那么这种高耦合度的结构也无可厚非,有时象底层软件如操作系统等,一切以执行效率优先,而且需求并不改变频繁的情况下,是适用的。但在实际开发过程中,软件需求的变化是导致这种模式被否定的真正原因。一旦有一个模块改变,那么需要改动到其它好几个模块,而且更要命的时,被影响的模块又会影响其它模块,或者干脆又把影响力传递给当初最先改动的模块。
下图中的模块结构通过梳理,使他们依附于一条粗线条,它是主逻辑模块,是相对稳定的高层的、抽象的模块。而其它通过一个小空心圆点(表示接口)与粗线条进行连接的小短线条代表次模块,它被分成两个部分,接口和实现接口的子类对象,它们通过接口与主逻辑模块形成依赖。相对来说,次模块变化较快,而主模块变化较慢。刚才提到的生活例子中,床相对于床单来说是主要的,核心的,成本较高的,它的使用年限是10年,而床单使用年限是2年,就是说床的模块变化速度慢于床单的变化速度,如果床2个月变一次,那么逻辑结构就混乱了。床为床单提供了一个尺寸接口,床单只要符合这个接口,就可以组合使用。那么这个接口就必须是相对稳定的。
设计模式做为软件开发过程中一种创造性的总结思维,使软件开发人员,在开发软件产品时,有了更加明确的软件解耦的思路,设计模式来源于生活,却指导于软件。事实上,短期来看,要求低耦合并没有很明显的好处,因为利用设计模式来解决问题是需要软件开发的智力和时间成本的。况且引入了误用设计模式的风险,所以短期内使用设计模式来解耦反而会影响系统的开发进度。低耦合的好处是长期回报的,体现在系统持续发展的过程中,系统具有更好的重用性,维护性,扩展性,持续的支持业务的发展,而不会成为业务发展的障碍。