单一职责原则
1.1 开闭原则定义
在面向对象领域中,开闭原则规定软件中的对象、类、模块和函数对扩展应该是开放的,但对于修改是封闭的。这意味着应该用抽象定义结构,用具体实现扩展细节,以此确保软甲系统的开发和维护过程的稳定性。
开闭原则的核心思想也可以理解为面向抽象编程。
1.2 模拟场景
对于外部调用方来说,只要能体现出面向抽象编程,定义出接口并实现其方法,即不修改原有的方法,之通过继承方式进行扩展,都可以体现出开闭原则。
这里计算三种形状的面积,如长方形、三角形、圆形,它们在类中已经按照固定的公式实现,其中圆形面积公式中∏=3.14。但是后续∏值取的精度对于某些场景是不足的,需要扩展,接下来就通过模拟这个场景体现开闭原则。
(1)定义接口。分别定义了三种求面积的接口。
public interface ICalculationArea {
/**
* 计算面积,长方形
* @param x 长
* @param y 宽
* @return 面积
*/
double rectangle(double x,double y);
/**
* 计算面积,三角形
* @param x 边长x
* @param y 边长y
* @param z 边长z
* @return 面积
*/
double triangle(double x,double y,double z);
/**
* 计算面积,圆形
* @param r 半径
* @return 面积
* 园面积计算公式:S=∏r²
*/
double circular(double r);
}
- 长方形面积,长×宽
- 三角形面积,使用海伦公式
- 圆形面积,S=Πr²
(2)实现类,在实现类中,分别实现三种类型的计算方式,长方形(rectangle)、三角形(triangle)、圆形(circular)。其中圆形面积的Π取值3.14D,这也是要扩展精度的方法和体现开闭原则的地方。
/**
* 计算面积实现类
*/
public class CalculationArea implements ICalculationArea {
private final static double n = 3.14D;
@Override
public double rectangle(double x, double y) {
return x * y;
}
@Override
public double triangle(double x, double y, double z) {
double p = (x + y + z) / 2;
return Math.sqrt(p * (p - x) * (p - y) * (p - z));
}
@Override
public double circular(double r) {
return n * r * r;
}
}
1.3 违背原则方案
如果不考虑开闭原则,那么直接修改Π的值就可以了,但是这样做就会破环整个工程服务的稳定性,也会造成一定风险。
例如,用原来精度的Π值计算出的圆形面积可以满足需求,但是精度的加长破环了原有精度的稳定性,就像齿轮间的啮合程度,方向盘的间隙等。
private final static double n = 3.141592653D;
public double circular(double r) {
return n * r * r;
}
1.4 开闭原则改善代码
按照开闭原则改善代码并不困难,它主要的目的是不能因为个例需求的变化而改变预定的实现类,除非预定的实现类有错误。
实现过程是通过继承父类扩展需要的方法,同时保留原有的方法,新增自己需要的方法。
/**
* 开闭原则改善代码
*/
public class CalculationAreaExt extends CalculationArea {
private final static double n = 3.141592653D;
@Override
public double circular(double r) {
return n * r * r;
}
}
扩展后的方法已经对Π的精度进行增长,需要使用此方法的用户可以直接调用。而其他方法,如长方形、三角形则可以继续使用。