前置知识
- 有项目编写经历
- 做过代码的功能拓展
- 听说过设计模式
前言
本文带大家继续学习 开闭原则
由于在软件体系中,唯一不变的,就是软件一直在变。这就意味着我们的软件、系统,需要把可拓展性做好,才不会让后期的功能拓展变得困难。事实上,大多数的设计模式都是在提高代码的可拓展性。而 开闭原则 就是提高代码可拓展性的核心原则。
开闭原则 定义
在面向对象编程领域中,开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。该特性在产品化的环境中是特别有价值的,在这种环境中,改变源代码需要代码审查,单元测试以及诸如此类的用以确保产品使用质量的过程。遵循这种原则的代码在扩展时并不发生改变,因此无需上述的过程。
上述的定义来自 百度百科 。其精髓部分是,对拓展开发,对修改关闭。意思是说,我们不能去修改原有功能的代码,但是可以利用面向对象特性,在不修改原有代码的基础上进行功能的拓展。
什么样的代码不符合开闭原则
开闭原则的定义很清晰,但是想理解和应用起来却感觉很抽象。下面我们结合一段代码来看看,什么样的代码是不符合开闭原则的
public class Work{ private A a; private B b; public Work(A a , B b){ this.a = a; this.b = b; } public void process(String processA,String processB){ ... actionA(a,processA); actionB(b,processB); } } 复制代码
上述的代码中,在 process()
部分,实现了 actionA 和 actionB 两个功能。
而当我们想要拓展一个功能 actionB 的时候,会做如下修改
public class Work{ private A a; private B b; private C c;//修改 public Work(A a , B b , C c){ this.a = a; this.b = b; this.c = c;//修改 } public void process(String processA,String processB,String processC){//修改 ... a.actionA(processA); b.actionB(processB); c.actionC(processC);//修改 } } 复制代码
可见,上述对功能的拓展中,其修改了核心函数的参数,所以这类修改不符合开闭原则。
因为直接修改了核心代码,会导致原有对该函数的调用会出错,需要修改入参的值。少量代码需要修改还好说,但是当代码里逐渐变大,每次添加新功能,都会需要修改大量的代码。而且,原有的单例测试代码也将不能正确运行。
如何让代码符合开闭原则
需要将代码修改得符合开闭原则,就需要把开闭原则的对 修改关闭 落实。
如下方的代码,我们需要将代码中会变化的参数 提取出来成为一个单独的类 ,这样子便于后面对参数的添加和删除。
public class WorkBean{ private A a; private B b; public void setA(A a){ this.a = a; } public A getA(){ return a; } ... ... } public class Processbean{ private String processA; private String processB; ... } 复制代码