开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则; 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节; 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则
使用前
需求:计算不同形状的面积
先完成计算三角形、长方形的面积的需求
package com.javaxl.design.rules.ocp.before;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:35
*
* 抽象的图形
*/
public class Shape {
public double getResult(){
if(this instanceof Triangle){
return ((Triangle) this).getWidth()*((Triangle) this).getHeight()/2;
}else if(this instanceof Rectangle){
return ((Rectangle) this).getHeight()*((Rectangle) this).getWidth();
}
return 0;
};
}
package com.javaxl.design.rules.ocp.before;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:38
* 三角形
*/
public class Triangle extends Shape{
private double width;
private double height;
public Triangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
}
package com.javaxl.design.rules.ocp.before;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:40
* 长方形
*/
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
}
package com.javaxl.design.rules.ocp.before;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:41
*/
public class Client {
public static void main(String[] args) {
// 计算三角形的面积
Triangle triangle = new Triangle(3,5);
System.out.println("计算三角形的面积:"+triangle.getResult());
// 计算长方形的面积
Rectangle rectangle = new Rectangle(3,5);
System.out.println("计算长方形的面积:"+rectangle.getResult());
}
}
需求发生变更:此时需要新增圆形的计算面积的方式
变更的代码如下:
package com.javaxl.design.rules.ocp.beforePlus;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 11:21
*/
public class Circular extends Shape {
private double r;
public Circular(double r) {
this.r = r;
}
public double getR() {
return r;
}
}
public class Shape {
public double getResult(){
if(this instanceof Triangle){
return ((Triangle) this).getWidth()*((Triangle) this).getHeight()/2;
}else if(this instanceof Rectangle){
return ((Rectangle) this).getHeight()*((Rectangle) this).getWidth();
}else if(this instanceof Circular){
return ((Circular) this).getR()*((Circular) this).getR()*3.14;
}
return 0;
};
}
public class Client {
public static void main(String[] args) {
// 计算三角形的面积
Triangle triangle = new Triangle(3,5);
System.out.println("计算三角形的面积:"+triangle.getResult());
// 计算长方形的面积
Rectangle rectangle = new Rectangle(3,5);
System.out.println("计算长方形的面积:"+rectangle.getResult());
// 计算圆形的面积
Circular circular = new Circular(2);
System.out.println("计算圆形的面积:"+circular.getResult());
}
}
使用后
实现三角形、长方形的面积计算
package com.javaxl.design.rules.ocp.after;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:35
*
* 抽象的图形
*/
public abstract class Shape {
public abstract double getResult();
}
package com.javaxl.design.rules.ocp.after;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:40
* 长方形
*/
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double getResult() {
return this.height*this.width;
}
}
package com.javaxl.design.rules.ocp.after;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:38
* 三角形
*/
public class Triangle extends Shape {
private double width;
private double height;
public Triangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double getResult() {
return this.height*this.width/2;
}
}
package com.javaxl.design.rules.ocp.after;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:41
*/
public class Client {
public static void main(String[] args) {
// 计算三角形的面积
Triangle triangle = new Triangle(3,5);
System.out.println("计算三角形的面积:"+triangle.getResult());
// 计算长方形的面积
Rectangle rectangle = new Rectangle(3,5);
System.out.println("计算长方形的面积:"+rectangle.getResult());
}
}
需求发生变更:此时需要新增圆形的计算面积的方式
变更的代码如下:
package com.javaxl.design.rules.ocp.afterPlus;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 11:16
*/
public class Circular extends Shape {
private double r;
@Override
public double getResult() {
return 3.14*r*r;
}
public Circular(double r) {
this.r = r;
}
}
package com.javaxl.design.rules.ocp.afterPlus;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 10:41
*/
public class Client {
public static void main(String[] args) {
// 计算三角形的面积
Triangle triangle = new Triangle(3,5);
System.out.println("计算三角形的面积:"+triangle.getResult());
// 计算长方形的面积
Rectangle rectangle = new Rectangle(3,5);
System.out.println("计算长方形的面积:"+rectangle.getResult());
// 计算圆形的面积
Circular circular = new Circular(2);
System.out.println("计算圆形的面积:"+circular.getResult());
}
}
从上面的可以看出
如果不遵循开闭原则:shape作为主体的类,一旦发生需求的变更,shape需要做对应的修改;
如果遵循了开闭原则,shape作为主体的类无需修改;只需要扩展其子类即可;
这就是“对扩展开放,对修改关闭”的含义;
概念
降低类的复杂度,一个类只负责一项职责 提高类的可读性,可维护性 降低变更引起的风险,对于服务端的代码尽量做到只新增不修改
上面计算图形面积的案例也体现了单一职责原则:
使用单一职责前:计算面积的逻辑全部耦合在shape类;
使用单一职责后:计算面积的逻辑交给各个子类去实现;
概念
一个对象应该对其他对象保持最少的了解 类与类关系越密切,耦合度越大 陌生的类最好不要以局部变量的形式出现在类的内部
其实就是单一职责原则的另一体现形式,将功能封装再封装,不要将所有的功能冗余在一起;
over......
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有