理念:
软件实体(类、模块、函数等等)应对扩展开放、而对修改关闭;
案例:
小明在工作中接到一个需求,需要提供一个加法的实现方法,于是他创建了一个Calculator
类,然后在里面定义并实现了一个add
方法,如下:
/**
* 计算器
*/
public class Calculator {
/**
* 加法
*/
public int add(int a, int b) {
return a + b;
}
}
第二天他又接到一个需求,需要提供一个减法的实现方法,于是他在Calculator
类中新增了一个subtract
方法,如下:
/**
* 计算器
*/
public class Calculator {
/**
* 加法
*/
public int add(int a, int b) {
return a + b;
}
/**
* 减法
*/
public int subtract(int a, int b) {
return a - b;
}
}
第三天他再次接到一个需求,需要提供一个乘法的实现方法,于是他在Calculator
类中又新增了一个multiply
方法,如下:
/**
* 计算器
*/
public class Calculator {
/**
* 加法
*/
public int add(int a, int b) {
return a + b;
}
/**
* 减法
*/
public int subtract(int a, int b) {
return a - b;
}
/**
* 乘法
*/
public int multiply(int a, int b) {
return a * b;
}
}
第四天…
从上面的案例来看,由于需求的增加,导致Calculator类不断的被修改,这就违背了开闭原则
;
同样是上面的案例,当懂得开闭原则的小红遇到时,会怎样来设计呢?接下来请看:
首先定义一个算法接口Algorithm
,在里面定义一个抽象方法calculate
,如下:
/**
* 算法
*/
public interface Algorithm {
/**
* 计算
*/
int calculate(int a, int b);
}
然后再重新定义Calculator
类,在里面新增一个Algorithm
类型的成员变量,同时定义并实现一个calculate
方法,如下:
/**
* 计算器
*/
public class Calculator {
private final Algorithm algorithm;
public Calculator(Algorithm algorithm) {
this.algorithm = algorithm;
}
/**
* 计算
*/
public int calculate(int a, int b) {
return algorithm.calculate(a, b);
}
}
当遇到需要提供一个加法的实现方法需求时,小红立马写了一个加法算法类AddAlgorithm
并实现了Algorithm
接口,如下:
/**
* 加法算法
*/
public class AddAlgorithm implements Algorithm {
@Override
public int calculate(int a, int b) {
return a + b;
}
}
当客户端需要调用该加法的实现方法时,只需要将创建的AddAlgorithm
实例注入到Calculator
的实例中,调用Calculator
实例的calculate
方法即可;
/**
* 客户端
*/
public class Client {
public static void main(String[] args) {
Algorithm algorithm = new AddAlgorithm();
Calculator calculator = new Calculator(algorithm);
int sum = calculator.calculate(3, 1);
System.out.println("result: " + sum);
}
}
// 运行结果
result: 5
当再遇到需要提供一个减法的实现方法需求时,小红再写了一个减法算法类SubtractAlgorithm
并实现了Algorithm
接口,如下:
/**
* 减法算法
*/
public class SubtractAlgorithm implements Algorithm {
@Override
public int calculate(int a, int b) {
return a - b;
}
}
客户端调用如下:
/**
* 客户端
*/
public class Client {
public static void main(String[] args) {
// Algorithm algorithm = new AddAlgorithm();
// Calculator calculator = new Calculator(algorithm);
// int sum = calculator.calculate(3, 2);
// System.out.println("result: " + sum);
Algorithm algorithm = new SubtractAlgorithm();
Calculator calculator = new Calculator(algorithm);
int sum = calculator.calculate(3, 2);
System.out.println("result: " + sum);
}
}
// 运行结果
result: 1
从上面小红的代码来看,即便再遇到新的算法需求,也只需要新增对应的算法实现类即可,并不会去修改已有的Calculator
类的代码,这就遵循了开闭原则的理念;
相关链接: