前言: 设计模式是我半年左右会回顾的知识点,因为半年的编码沉淀,再次复习会让自己对设计有一些新的体悟。
这是第一集:https://www.cnblogs.com/Gabby/p/10391126.html
设计原则
1. 单一职责原则-SRP
- 前提:面向接口编程原则
- 接口一定要做到单一职责;
- 类的设计尽量做到只有一个原因引起变化;
- 一个方法尽量只做一件事
2. 里氏替换原则-LSP
-
定义
- 所有引用积累的地方能透明底使用其子类的对象,只要父类能出现的地方子类都可以出现
-
4个含义
- 子类必须完全实现父类的方法,当不想继承父类时,可以脱离继承,建立一个独立的父类,也就是抽象类,然后再继承这个抽象类【依赖,聚合和组合等】
- 子类可以有自己的个性,但是有子类的地方父类未必就可以出现
- 覆盖或实现父类的方法时输入参数可以被放大
- 覆盖或实现父类的方法时返回值可以被缩小
-
采用里氏替换原则的目的是增强程序的健壮性,即使增加子类,原有的子类也能继续运行,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑。
3. 依赖倒置原则-DIP
-
定义-面向接口编程
- 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或实现类产生的
- 接口或抽象类不依赖于实现类
- 实现类依赖接口或抽象类
-
测试驱动开发:当抽象类未完成时,可以根据抽象虚拟一个对象进行测试。
-
依赖的三种写法:
- 在构造函数中注入
- 在setter方法中注入,传递依赖对象
- 在参数中进行传递
-
DIP的最终原则是通过抽象使各个类或模块实现彼此独立,不相互影响,实现模块间的松耦合,写代码的原则:
- 每个类尽量有接口或抽象类
- 变量的定义类型尽量是接口或是抽象类
- 任何类都不应该从具体的类中继承
- 尽量不要覆写抽象父类的方法
- 接口负责定义public属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现,实现类准确地实现业务逻辑,同时在适当的时候对父类进行细化
4. 接口隔离原则
-
定义
- 客户端不依赖他不需要的接口;对接口进行细化,保证接口的纯洁性
- 类间的依赖关系应该建立在最小的接口上;要求接口细化,接口纯洁,
- 要求接口方法尽量少
-
接口隔离原子对接口进行规范约束:
- 接口要尽量小,但前提是满足违反单一职责
- 接口要高内聚:public方法应该只是对外的服务,尽量少公布public方法
- 只提供访问者需要的方法
-
实践原则
- 一个接口只服务于一个子模块或业务逻辑
- 通过业务逻辑压缩接口中的public方法
- 对于以及污染的接口,使用适配器模式进行转化处理
5. 迪米特法则
-
定义
- 一个对象应该对其他对象有最少的了解,一个类应该对自己需要耦合或调用的类知道地最少
-
含义
- 一个类中的方法尽量不要引入没有出现在类的成员变量或者方法的输入输出参数的对象
- 尽量对外公布少的public方法
- 如果一个方法放在本类中,既不增加类间关系,对本类不产生负面影响,就放在本类中
-
实践原则
- 类间解耦,弱耦合
- 如果一个类跳转两次以上才能访问另一个类,那就需要考虑重构了
6. 开闭原则
-
定义
- 一个软件实体,如类, 模块和函数,应该对扩展开放,对修改关闭
-
变化
- 逻辑变化:如果所有依赖或关联类都按照相同的逻辑处理,可以通过修改原有类中的方法来完成
- 子模块的变化:通过扩展修改低层次模块时,高层次模块的修改是必然的
-
实践原则
- 对接口或抽象类进行约束一组可能变化的行为,并且能够实现对扩展开放
- 参数类型,引用对象尽量使用接口或者抽象类,而不是实现类
- 抽象层尽量保持稳定,一旦确定即不允许修改
- 尽量使用元数据来控制程序的行为,减少重复开发,spring就是一个很好的例子
- 将相同的变化封装在一个接口或抽象类中