在哲学上,矛盾法则即对立统一的法则,是唯物辩证法的最根本法则。开闭原则(OCP)是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。开闭原则的定义:
- 一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
开闭原则的定义已经非常明确的地告诉我们:软件实体应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。软件实体包括以下几个部分:
- 项目或软件产品中按照一定的逻辑规则划分的模块。
- 抽象和类。
- 方法。
开闭原则告诉我们应尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来完成变化,它是为软件实体的未来事件而制定的对现行开发设计进行约束的一个原则。开闭原则对扩展开放,对修改关闭,并不意味着不做任何的修改,低层模块的变更,必然要有高层模块进行耦合,否则就是孤立无意义的代码片段。
开闭原则是最基础的一个原则,其他的五种原则都是开闭原则的具体形态,而开闭原则才是其精神领袖。
开闭原则的重要性:
- 开闭原则对测试的影响
所有已经投产的代码都是有意义的,并且都受系统规则的约束,这样的代码都要经过“千锤百炼”的测试过程,不仅保证逻辑是正确的,还要保证苛刻条件(高压力、异常、错误)下不产生“有毒代码”,因此有变化提出时,我们就需要考虑一下,原有的健壮代码是否可以不修改,仅仅通过扩展实现变化。否则,就需要把原有的测试过程回笼一遍,需要进行单元测试、功能测试、集成测试甚至是验收测试。 - 开闭原则可以提高复用性
在面向对象的设计中,所有的逻辑都是从原子逻辑组合而来的,而不是在一个类中独立实现一个业务逻辑。只有这样的代码才可以复用,粒度越小,被复用的可能性就越大。 - 开闭原则可以提高可维护性
- 面向对象开发的要求
如何使用开闭原则:
- 抽象约束
抽象是对一组事物的通用描述,没有具体的实现,也就表示化可以有非常多的可能性,可以跟随需求的变化而变化。因此,通过接口或抽象类可以约束一组可能变化的行为,并且能够实现对扩展开放,其包含三层含义:1.通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public
方法。2.参数类型、引用对象尽量使用接口或者抽象类,而不是实现类。3.抽象层尽量保持稳定,一量确定即不允许修改。 - 元数据(metadata)控制模块行为
编程是一个很苦很累的活,那怎么才能减轻我们的压力呢?答案是尽量使用元数据来控制程序的行为,减少重复开发。什么是元数据?用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据库中获得。 - 制定项目章程
在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。 - 封装变化
对变化的封装包含两层含义:1.将相同的变化封装到一个接口或抽象类中;2.将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。封装变化,也就是受保护的变化,找出预计有变化或不稳定的点,我们为这些变化点创建稳定的接口,准确地讲是封装可能发生的变化,一旦预测到有变化,就可以进行封装。
23种设计模式都是从各个不同的角度对变化进行封装。