高内聚松耦合在程序设计中如何做到
内聚:一个模块内各个元素彼此结合的紧密程度
耦合:一个软件结构内不同模块之间互连程度的度量
我们一直追求着,高内聚,低耦合。
对于低耦合的理解是:
一个完整的系统,模块与模块之间,尽可能的使其独立存在。
也就是说,让每个模块,尽可能的独立完成某个特定的子功能。
模块与模块之间的接口,尽量的少而简单。
如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。
这样有利于修改和组合。
对于低耦合的理解是:
在一个模块内,让每个元素之间都尽可能的紧密相连。
也就是充分利用每一个元素的功能,各施所能,以最终实现某个功能。
如果某个元素与该模块的关系比较疏松的话,可能该模块的结构还不够完善,或者是该元素是多余的。
内聚和耦合,包含了横向和纵向的关系。功能内聚和数据耦合,是我们需要达成的目标。横向的内聚和耦合,通常体现在系统的各个模块、类之间的关系,而纵向的耦合,体现在系统的各个层次之间的关系。
对于我在编码中的困惑,我是这样想的,用面向对象的思想去考虑一个类的封装。
一个方法,如何封装,拿到现实生活中来看,看这种能力(方法)是否是属于这类事物(类)的本能。
如果是,就封装在这个类里。
如果不是,则考虑封装在其它类里。
如果这种能力,很多事物都具有,则一定要封装在这类事物的总类里。
如果这种能力,很多事物都会经常用到,则可以封装成一个总类的静态方法。
人们不易实现松耦合,因为,孤独的模块毫无意义,只有模块间的相互协调地工作,才能实现系统的目的。而对于模块间的相互关系的设计,没有一定的经验是难以把握。耦合的强度依赖于:(1)一个模块对另一个模块的调用;(2)一个模块向另一个模块传递的数据量;(3)一个模块施加到另一个模块的控制的多少;(4)模块之间接口的复杂程度。等等。
当然,“强内聚、松耦合”也是有矛盾的,如:内聚性越强,则要求的函数越多(每个函数只作一件“事”),这样,将它们组合成“大”的功能,也就越复杂,就不可能达到松耦合。因此,应在二者之间作出平衡与折衷的选择,这也体现程序员的水平。从系统论的角度来看,系统是有层次的,即系统可以分为子系统,模块可分为子模块,“强内聚、松耦合”的“度”的把握,应结合系统的次层性来考虑,即通常应在层次性上作出折衷,如:模块内子程序(下一个层次上)应共享数据(有一定的耦合度),而减少全局变量能降低子程序性间的耦合性。
面向对象的语言进一步强化了“强内聚、松耦合”,类的封装性既强调了相关内容(数据及其操作)的内聚,又强调了类的独立性和私密性。而类的继承性以及友元等,就是在松耦合的原则下规范了类之间的关联关系。类与类之间通常通过接口的契约实现服务提供者/服务请求者模式,这就是典型的松耦合。
“强内聚、松耦合”对于程序编写分工、程序的可维护性以及测试都有重要的关系,如:从设计角度来看,在“强内聚、松耦合”的指导下进行的设计得到的程序模块,符合项目管理的WBS(工作分解结构)的要求,其相对独立的模块可以分配到具体的程序员进行开发,另外,程序编码外包也必须建立在这种原则的设计之下;从程序生命期角度来看,它有利于提高程序质量,特别是方便于程序的日后维护,即程序模块的相对独立性是可维护性的保证;再从测试角度来看,符合“强内聚、松耦合”的程序,易于对局部(模块)进行黑盒测试,也易于编写测试用的“桩”和“驱动”。
“强内聚、松耦合”也是对组织结构的要求,项目组分为几个小组(正式的或非正式的),各小组的工作应是高度相关的,各小组之间的工作应尽量是较少相关或有明确的接口,从而减少沟通成本。其实,“强内聚、松耦合”是系统中应遵守的普遍原则,我们在许多领域都可以找到它的应用。高内聚的模块,互相之间依赖性比较少,某个模块一但出现问题的时候,能把错误控制在一个模块内.不会因为一个模块出了问题,而影响了其他功能模块.保证了其他功能的完整性,不会影响用户的其他操作,能让给用户带来的麻烦降低到最低限度.程序员也能快速的定位出问题所在的模块,进行问题修改.模块之间没有太多的牵连,更便于程序员的问题修改.在问题修改后,也不会给其他功能模块带来太多的影响.测试人员在做单元或集成测试的时候,能够更容易把里面的程序模块之间的逻辑理清楚,能设计出高覆盖率的用例把程序代码后模块接口都能完全覆盖测试到.也能让测试人员在做回归测试时,降低一定的风险.
耦合性高的模块,相互之间依赖性比较多,模块与模块之间的关系也比较复杂.就容易出现,一个程序模块出现了问题,导致其他功能模块都不能正常运行.而且由于关系的复杂性,给程序员定位及修改问题带来一定的不便.也影响了用户的所有操作,给用户带来更大损失.而且由于模块之间的复杂关系,即便程序员修改了一个问题后,也不能保证不会带来更多的缺陷.给测试人员做单元和集成测试带来了太多的不便.需要花大量的时间去理清内部的逻辑.在这样的情况下,可能也会给测试工作带来遗漏的地方,留下隐患.测试人员也要花更多的时间进行回归测试,来保证系统程序符合规定要求了.无形中给项目带来了更多的风险.
所以,在写大系统时尽量提高程序的内聚,降低程序的耦合程序。紧耦合意味着函数功能复杂并传递参数较多,将复杂功能的函数分解成功能独立的模块以实现:高内聚,松耦合。
专注 + 保持追求精益求精的精神 + 完美的心态 == 天才