【楔子】
大道至简,形而上学。
【内容】
①高内聚,低耦合
耦合(coupling):
模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则就是高内聚低耦合。
干货:
个人理解-耦合就是一个类对象和另一个类对象之间的交互及依赖关系;
譬如观察者模式主题类和观察者之间的关系,当主题类的状态发生变化时,会通知观察者类更新;但主题类与观察者是松耦合的关系,主题对象并不清楚观察者对象的内部细节,主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节。任何时候我们都可以增加新的观察者,主题不会受到任何影响。有新的观察者出现时,主题代码不需要修改。
通过使用接口,可以有效的降低耦合!
耦合层次:
一般模块之间可能的连接方式有七种,构成耦合性的七种类型。它们之间的关系为(独立性由强到弱)。
2)数据耦合:一个模块访问另一模块,彼此间通过简单数据参数来交换输入、输出信息。这里的简单数据参数不同于控制参数、公共数据结构或外部变量。
3)标记耦合:如一组模块通过参数表传递记录信息,就是标记耦合。这个记录是某一数据结构的子结构,不是简单变量。
4)控制耦合:一个模块通过传递开关、标志、名字等控制信息,明显的控制选择另一模块的功能
5)外部耦合:一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数传递该全局变量的信息
6)公共耦合:一组模块都访问同一个公共数据环境。该公共数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。
7)内容耦合:一个模块直接修改另一个模块的数据,或直接转入另一个模块 。
耦合的强度依赖于以下几个因素:
①一个模块对另一个模块的调用;
②一个模块向另一个模块传递的数据量;
③一个模块施加到另一个模块的控制的多少;
④模块之间接口的复杂程度
为什么要低耦合?
耦合度很高的情况下,维护代码时修改一个地方会牵连到很多地方,如果修改时没有理清这些耦合关系,那么带来的后果可能会是灾难性的,特别是对于需求变化较多以及多人协作开发维护的项目,修改一个地方会引起本来已经运行稳定的模块错误,严重时会导致恶性循环,问题永远改不完,开发和测试都在各种问题之间奔波劳累,最后导致项目延期,用户满意度降低,成本也增加了,这对用户和开发商影响都是很恶劣的,各种风险也就不言而喻了。
降低耦合度的方法
1、少使用类的继承,多用接口隐藏实现的细节。 java面向对象编程引入接口除了支持多态外, 隐藏实现细节也是其中一个目的。
2、模块的功能化分尽可能的单一,道理也很简单,功能单一的模块供其它模块调用的机会就少。
3、遵循一个定义只在一个地方出现。
4、少使用全局变量。
5、类属性和方法的声明少用public,多用private关键字,
6、多用设计模式,比如采用MVC的设计模式就可以降低界面与业务逻辑的耦合度。
7、尽量不用“硬编码”的方式写程序,同时也尽量避免直接用SQL语句操作数据库。
8、最后当然就是避免直接操作或调用其它模块或类(内容耦合);如果模块间必须存在耦合,原则上尽量使用数据耦合,少用控制耦合,
限制公共耦合的范围,避免使用内容耦合。
内聚:
内聚度是指内部各元素之间联系的紧密程度;通常是指类与类之间的关系。
高内聚,意思是他们之间的关系要简单,明了,不要有很强的关系,不然,运行起来就会出问题。
一个类的运行影响到其他的类。由于高内聚具备鲁棒性,可靠性,可重用性,可读性等优点,模块设计推荐采用高内聚。
1.可取的内聚性:
1)功能内聚性:最好的内聚性,程序仅执行一种功能。
2)顺序内聚性:子程序内包含按特定顺序执行、逐步分享数据而行成一个完整功能的操作。如文件的几种操作。
3)通讯内聚性:两个操作含有相同数据但又相互不存在联系。
4)临时内聚性:由于同时执行原因而放到一个子程序。
2.不可取的内聚性:
1)过程内聚性:子程序的操作按一特定顺序执行,而相互之间不共享数据。
2)逻辑内聚性:子程序含有几个操作,而个操作通过控制标志进行选择。
3)偶然内聚性:子程序操作间无任何联系。
【小结】
“高内聚,低耦合”,首先要知道一个软件是由多个子程序组装而成, 而一个程序由多个模块(方法)构成!
“高内聚,低耦合”主要是阐述的面向对象系统中,各个类需要职责分离的思想。
每一个类完成特定的独立的功能,这个就是高内聚。耦合就是类之间的互相调用关系;
如果耦合很强,互相牵扯调用很多,那么会牵一发而动全身,不利于维护和扩展。
【附录-软件设计准则】
①单一职责原则(Single Responsibility Principle,简称SRP)
②开放--封闭原则(The Open-Closed Principle,简称OCP)
③依赖倒转原则(Dependence Inversion Principle )
④里氏代换原则(Liskov Substitution Principle,简称LSP)
⑤迪米特法则(Law of Demeter)
⑥接口隔离原则(ISP)
⑦合成/聚合复用原则(Composition/Aggregation Principle],简称CARP)