敏捷开发读书笔记四
Liskov替换原则(LSP)
Liskov替换原则(LSP):子类型(subtype)必须能够替换掉它们的父类型(basetype)
- IS-A(是一个)关系又是被认为是面向对象分析的基本技术之一.
- 一个模型,如果孤立地看,并不具有真正意义上的有效性.模型的有效性只能通过它的客户程序来表现.
- 像所有其他原则一样,通常最好的方法是只预测那些最明显的对于LSP的违反情况二推迟所有的其他的预测,直到出现相关的脆弱性的臭味时,采取处理他们.
- IS-A是关于行为的.从行为方式的角度来看,Square不是Rectangle(关于正/长方形的例子),对象的行为方式才是软件真正所关注的问题.
- 基于契约设计(Design By Contract,DBC):使用DBC,类的编写者显示的规定针对该类的契约.客户代码的编写者可以通过该契约获悉可以依赖的行为方式.契约是通过为每个方法生命的前置条件(preconditions)和后置条件(postconditions)来制定的.要使一个方法得以执行,前置条件必须要为真.执行完毕后,该方法要保证后置条件为真.
- 大多数情况下,接受一个多态性为中的微妙错误都不会比试着修改设计使之完全符合LSP更为有利.接受缺陷而不是去追求完美这是一个工程中的权衡问题.好的工程师知道如何接受缺陷比追求完美更有利.
- 提取公共部分是一个设计工具,最好在代码不是很多时应用.
- 完成的功能少于基类的派生类通常是不能替换其基类的,一尺就违反了LSP
- 在派生类中存在退化函数并不总是表示违反了LSP,但是当存在这种情况是,还是值得注意一下.
- 另外一种LSP的违规形式是在派生类的方法中添加了其基类不会抛出的异常.
- LSP是使OCP成为可能的主要原则之一
依赖倒置原则(DIP)
依赖倒置原则(DIP):
a.高层模块不应该依赖于低层模块,二者都应该依赖于抽象
b.抽象不应该依赖于细节,细节应该依赖于抽象.
- DIP是框架设计的核心原则.
- 倒置不仅仅是依赖关系的倒置,也是接口所有权的倒置.应用DIP的时,往往是客户拥有抽象接口,而服务者则从这些抽象接口派生.
- 低层模块实现了在高层模块中声明并被高层模块调用的接口.
- 程序中所有的依赖关系都应该终止于抽象类或者接口
- 我们在应用程序中所编写的大多数具体类都是不稳定的,我们不想直接依赖于这些不稳定的具体类.通过把它们隐藏在抽象接口的后面,可以隔离它们的不稳定性.
- 面向对象的程序设计倒置了依赖关系结构,使得细节和策略都依赖于抽象,并且常常是客户拥有服务接口.这种依赖关系的倒置正式好的面向对象设计的标志所在.
- 如果程序的依赖关系是倒置的,它就是面向对象的设计.如果程序的依赖关系不是倒置的,它就是过程化设计.
- DIP的正确应用对于创建可重用框架来说是必须的.
接口隔离原则(ISP)
接口隔离原则:不应该强迫客户依赖于它们不用的方法.
- ISP用来处理”胖(fat)”接口所具有的缺点.如果类的接口不是内聚的(conhesive),就表示该类具有”胖”的接口.换句话说,类的”胖”接口可以分解成多组方法.每一组方法都服务于一组不同的客户程序.
- 多参数形式通常都应该优先于单参数形式使用.
- 每个原则在应用时都必须小心,不能过度使用它们.
- 客户程序应该仅仅依赖与它们的实际调用方法.通过把胖类的接口分解成多个特定于客户程序的接口,实现这个目标.