设计模式六大原则
一、单一职责原则
- 定义:不要存在多于一个导致类变更的原因。通俗的说就是,一个类只负责一项职责。
- 简述:这个比较容易理解,单一职责即只负责自己最应该负责的那一个特定的功能。否则,如果负责多项职责,当其中一个发生变化时,可能会对其他功能产生影响,可维护性、可读性、复杂性都会好。这个原则同样适用于方法级别和系统级别,甚至所有模块化的设计中。一般的开发中,都会遵循这个基本的常识,但问题往往出在需求的变更、结构的变化时。当发生变化时,往往会因为变化很小,新的职责只是很小一部分功能,而没有重新划分职责类,而是在原有的逻辑中继续添加。久而久之,积小成大,类的职责越来越模糊,体积也越来越庞大。但有时候为了很小的一个功能去重构,又有些不太值得。所以,在实际开发中,要学会酌情而定。一个可用的原则是:逻辑足够简单时,才可以在代码级别违反;当类的方法足够少时,才可以在方法级别违反;以此类推。。。当复杂度上升至一个临界点时,要当机立断,对职责重新进行明确划分,避免后面“大手术”的痛苦。
- 优点:
- 降低复杂度
- 提高可读性/可维护性
- 降低变更引起的风险
二、里氏替换原则
- 定义:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。
- 简述:简而言之就是子类可以扩展功能,但不要改变父类的方法,包括重写和重载。父类实现好的方法(不包括抽象方法)实际上已经定义了一些规范和约束,虽然java的继承机制支持重写,但该原则不鼓励这么做。因为这会破坏原有的继承机制,使系统变得不再简单。如果发现在开发过程中,经常出现“不得不”违反该原则的情况,可能是你的基类设计的不够好,或者干脆当前的场景不适合运用继承机制,可以改用依赖、聚合、组合等其他方式进行重新设计。
- 优点:
- 保证相对良好、简单的继承机制
- 提高重用性、
- 降低出错的几率
三、依赖倒置原则
- 定义:高层模块不应该依赖低层模块,二者都应该依赖低层抽象;抽象不应该依赖细节;细节应该依赖抽象。
- 简述 :依赖倒置原则其实核心就是面向接口编程。当我们编写一个上层逻辑时,如果直接依赖低层类,就等于依赖了具体的实现,当具体的实现变化时,我们的结构就容易发生危险变得不稳定。抽象则相反,越抽象的东西越稳定,例如抽象类和接口。使用抽象类和接口的目的就是制定好规范和约束,而不去设计具体的细节。通过抽象,将细节和变化隔离开来,从而增加了稳定性。遵循依赖倒置原则需要做到三点:
- 低层模块尽量都要有抽象类或接口
- 变量的声明类型尽量使用抽象类或接口
- 使用继承时,遵循里氏替换原则
四、接口隔离原则
- 定义 : 客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
- 简述 : 如果一个接口I定义了方法f1和f2,类A通过I依赖f1,类B通过I依赖f2,那么此时A和B都要不得不实现一个他们并不需要的方法。好的设计应该通过将I分解为多个接口,A和B分别去实现各自的依赖,也就是采用接口隔离原则。采用接口隔离原则要注意这几点:
- 接口要尽量小,单要有限度。细化到符合接口隔离原则就好,否则太过细化的话,会导致接口数量过多,设计变得复杂化。
- 只暴露给易赖接口的类它需要的方法,缩小依赖关系。
- 提高内聚,减少对外交互。
这一原则的尺度需要在时机开发设计中慢慢体会,找到细化的一个度,才能更好的实践这一原则。
五、迪米特法则
- 定义 : 一个对象保持对其他对象的最少了解
- 简述 : 了解的越多,耦合越大,变动产生的影响也就越多。所以要尽量保持最少的了解,降低耦合。一个类无论他多么复杂,要讲复杂逻辑封装在类的内部,对外只提供简单稳定的入口。迪米特法则还有个更简单的定义:只与直接的朋友通信。与一个类产生关系的其他类,我们称之为朋友。关系有很多种,出现在成员变量、方法参数、方法返回值中的类我们成为直接朋友。以局部变量形式出现的类,不是直接朋友。所以迪米特法则告诉我们,要避免类以局部变量的形式出现。在实际设计和实现中,该法则体现了面向接口编程的思想。在类的设计、接口的设计时,通常会将相互间的依赖关系经过深思熟虑的巧妙安排,使其尽量稳定、可扩展。这些设计中,就包含了直接朋友:成员变量、方法参数、返回类型。如果在类和接口实现的内部,引入了设计以外的其他类,也就是间接朋友,这在一定程度上破坏了设计,增加了复杂度。当简介朋友变化时,引入它的地方很大可能会受到影响。而这些在接口设计层面是不可见的,排除、解决问题的难度也就增加了。如果需要与非直接朋友发生某些关系,可以通过直接朋友作为媒介来通信。做到结构清晰,高内聚、低耦合。
- 定义 : 一个软件实体如类、模块、函数等应该对扩展开放,对修改关闭。
- 简述 : 开闭原则是对设计的一个更模糊但更全面的约束。他表达了一种概念:用抽象构建框架,用实现扩展细节。因为抽象是更稳定、更灵活的,用它来构建框架,可以保持稳定性。而细节是易变的,我们用从抽象派生的实现来扩展细节。当需求变化时,如果框架抽象的合理,多数情况下,我们只需根据需求重新派生实现类就可以了。当然,前提是抽象一定要合理,并具有一定的前瞻性。在实际设计和开发中,遵循好前五大原则的目的和结果往往就是开闭原则。