设计模式之开闭原则
开闭原则
一、概念
在面向对象编程领域中,开闭原则规定软件中的类、对象、模块和函数对扩展应该是开放的,但是对于修改来说是封闭的。
这就意味着应该用抽象定义结构,用具体实现扩展细节,以此确保软件系统开发和维护过程中的可靠性。
开闭原则的核心思想可以理解成为面向抽象编程。
二、案例
对于外部的调用方来说,只需要能够体现出来面向抽象编程,定义出接口并实现其方法。
即使不修改原有方法体,只通过继承方式进行扩展,都可以体现出开闭原则。
比如说:计算出来三种形状的面积,如长方形、三角形、原型的面积,他们在类中已经按照固有的模式来进行实现,其中圆形面积公式π=3.14。但是由于后续π的精度对于某些场景来说是不足的,还需要来进行扩展,接下来通过模拟这个场景来体现出开闭原则。
代码如下所示:
/**
* @Description 但是对于三个类来说,都是计算面积的,但是针对于不同的具体的类来说,有不同的实现方式
* 那么这样子来进行操作的话,有违单一职责原则;所以这里不能够这样子来进行使用!
* @Author liguang
* @Date 2022/04/06/00:02
*/
public interface ICalculateionArea {
/**
*计算长方形的面积
* @param x 长方形的唱
* @param y 长方形的款
* @return
*/
double rectangle(double x,double y);
/**
* 计算三角形的面积 s = 根号p*(p-a)*(p-b)*(p-c),其中p=(a+b+c)/2
* @param x 一条边
* @param y 一条边
* @param z 一条边
* @return
*/
double triandle(double x ,double y,double z);
/**
* 计算圆形面积
* @param r 圆的半径
* @return
*/
double circular(double r);
}
查看一下对应的实现类:
public class CalculateionArea implements ICalculateionArea {
private final double PAI = 3.14D;
@Override
public double rectangle(double x, double y) {
return x*y;
}
@Override
public double triandle(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 PAI*r*r;
}
}
编写对应的测试类:
public class Test {
public static void main(String[] args) {
CalculateionArea calculateionArea = new CalculateionArea();
double triandleArea = calculateionArea.triandle(3, 4, 5);
System.out.println("三角形的面积是:"+triandleArea);
double circularArea = calculateionArea.circular(3);
System.out.println("圆形的面积是:"+circularArea);
double rectangleArea = calculateionArea.rectangle(1, 2);
System.out.println("长方形的面积是:"+rectangleArea);
}
}
三、对案例进行扩展
但是现在有了新的业务需要单独的进行扩展下,需要的π的精度需要更高一点,但是如果修改了原来的值,肯定是违反了开闭原则的。会对原来的业务功能造成对应的错误(隐藏的),所以为了现有的实现类不对原来的实现类造成影响,那么选择一个新的类来对其进行继承,以继承的方式来进行选择实现新的功能。
对应的格式如下所示:
/**
* @Description 想要在此基础之上来进行修改操作
* @Author liguang
* @Date 2022/04/06/00:15
*/
public class CalculateionAreaExt extends CalculateionArea{
private final double PAI = 3.1495926D;
@Override
public double circular(double r) {
return PAI*r*r;
}
}
那么这样子也就意味着可以对原来的功能没有影响,而且这里也可以来进行面向抽象编程,和原来的功能是一样的。
编写对应的测试类,如下所示:
public class TestExt {
public static void main(String[] args) {
ICalculateionArea calculateionArea = new CalculateionArea();
double triandleArea = calculateionArea.triandle(3, 4, 5);
System.out.println("三角形的面积是:"+triandleArea);
double circularArea = calculateionArea.circular(3);
System.out.println("圆形的面积是:"+circularArea);
double rectangleArea = calculateionArea.rectangle(1, 2);
System.out.println("长方形的面积是:"+rectangleArea);
System.out.println("---------------------------");
System.out.println("-----------------------------------");
System.out.println("-----------------------------------");
System.out.println("-----------------------------------");
System.out.println("-----------------------------------");
ICalculateionArea calculateionAreaExt = new CalculateionAreaExt();
double circularAreaExt = calculateionAreaExt.circular(3);
System.out.println("圆形的面积是:"+circularAreaExt);
}
}
这样子来进行操作也不失为一个好的方法。
四、核心思想
对修改关闭,对扩展开放!面向抽象编程
从理论中来,到实践中去,最终回归理论