开放封闭原则(OCP,Open Closed Principle)都是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。
核心的思想是:软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。因此,对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
基本思路:实现开放封闭的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以对修改就是封闭的;而通过面向对象的继承和对多态机制,可以实现对抽象体的继承,通过覆写其方法来改变固有行为,实现新的扩展方法,所以对于扩展就是开放的。
规则建议
- 开放封闭原则,是最为重要的设计原则,Liskov替换原则和合成/聚合复用原则为开放封闭原则的实现提供保证。
- 可以通过Template Method模式和Strategy模式进行重构,实现对修改封闭、对扩展开放的设计思路。
- 封装变化,是实现开放封闭原则的重要手段,对于经常发生变化的状态一 般将其封装为一个抽象,例如银行业务中的IBankProcess接口。
- 拒绝滥用抽象,只将经常变化的部分进行抽象,这种经验可以从设计模式的学习与应用中获得。
--------------------------------------------------------------------------------------------------------------------------------------------------
依赖倒转原则(DIP,Depend Invert Principle)
核心的思想是:要依赖于抽象,不要依赖于具体。或者说是:要针对接口编程,不要对实现编程(Program to an interface, not an implementation)。
基本思路:当我们使用接口和抽象类进行变量的类型声明、方法的返回类型说明,以及数据类型的转换等。要保证做到这一点,一个具体的类应当只实现接口和抽象类中声明过的方法,而不应当给出多余的方法。
引用对象的抽象类型:只要一个被引用的对象存在抽象类型,就应当在任何引用此对象的地方使用抽象类型,包括参量的类型声明、方法的返回类型的声明、属性变量的类型声明等。
联合使用接口和抽象类:由于抽象类具有提供缺省实现的优点,而接口具有其他的优点,所以联合使用两者是很好的选择。首先,声明类型的工作是由接口承担,但是同时给出的还有一个抽象类,为这个接口提供一个缺省实现。其他同属于这个抽象类型的具体类可以选择实现这个接口,也可以选择继承自这个抽象类。如果需要向接口加入一个方法的话,只要同时向这个抽象类加入这个方法的具体实现就可以了,因为继承自这个抽象类的子类都会从这个抽象类得到这个具体方法。
优点:系统扩展灵活。缺点:需要大量的类。