From Now On,Let us begin Design Patterns。
开放封闭原则 Open Closed Principle
定义
- 一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。 Software entities like classes, modules and functions should be open for extension but closed for modifications.
所谓开放封闭原则就是软件实体应该对扩展开发,而对修改封闭。开放封闭原则是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化,降低耦合,而开放封闭原则正是对这一目标的最直接体现。
开放封闭原则主要体现在两个方面:
对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
对修改封闭,意味着类一旦设计完成,就可以独立其工作,而不要对类做任何修改。
为什么要用到开放封闭原则呢?
软件需求总是变化的,世界上没有一个软件的是不变的,因此对软件设计人员来说,必须在不需要对原有系统进行修改的情况下,实现灵活的系统扩展。
如何做到对扩展开放,对修改封闭呢?
实现开放封闭的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以对修改就是封闭的;而通过面向对象的继承和多态机制,可以实现对抽象体的继承,通过覆写其方法来改变固有行为,实现新的扩展方法,所以对于扩展就是开放的。
对于违反这一原则的类,必须通过重构来进行改善。常用于实现的设计模式主要有Template Method模式和Strategy 模式。而封装变化,是实现这一原则的重要手段,将经常变化的状态封装为一个类。
我们对扩展实现了开放,才能够保证对修改是封闭的。开放利用了对象的抽象,封闭则在一定程度上利用了封装。最佳的做法仍然是要做到分离对象的变与不变,将对象不变的部分封装起来,并遵循良好的设计原则以保障接口的稳定;至于对象中可能变的部分,则需要进行抽象,以建立松散的耦合关系。
回忆前面的5个原则,OCP恰恰告诉我们:用抽象构建框架,用实现扩展细节的注意事项而已:
单一职责原则告诉我们实现类要职责单一
里氏替换原则告诉我们不要破坏继承体系
依赖倒置原则告诉我们要面向接口编程
接口隔离原则告诉我们要在设计接口时要精简单一
最少知识原则告诉我们要降低耦合
而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。
在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。[解决方案]当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化.只要遵循以下的几个规则就可以:
如何遵循抽象约束:
通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中的不存在的public方法
参数类型、引用对象尽量使用接口或者抽象类,而不是实现类
这样当我们修改具体的实现类的时候才不需要修改这些参数。抽象层尽量保持稳定,一旦确定即不允许修改
我们必须保证一个接口,尤其要保证被其他对象调用的接口的稳定;否则,就会导致修改蔓延,牵一发而动全身。从某种程度上讲,接口就是标准,要保障接口的稳定,就应该对对象进行合理的封装。一般的设计原则之所以强调方法参数尽量避免基本类型,原因正在于此。
封装变化:
将相同的变化封装到一个接口或抽象类中
子类只需要继承或者使用这个接口就可以定义自己需要的功能将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一接口或抽象类中
23设计模式也是从各个不同的角度对变化进行了封装
原则的优点
开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭,其他五个原则只是为了可以实现第六个原则而提供的一些基础理论:
1. 使单元测试也能够OCP
2. 帮助缩小逻辑粒度,以提高可复用性
3. 可以使维护人员只扩展一个类,而非修改一个类,从而提高可维护性
4. 在设计之初考虑所有可能变化的因素,留下接口,从而符合面向对象开发的要求