开闭原则(Open/Closed Principle,简称OCP)是面向对象设计中的一个原则,它规定一个软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。简而言之,对于已有的代码,应该通过扩展来实现新的功能,而不是通过修改已有的代码。
反例:
public class Rectangle {
protected double width;
protected double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
public class AreaCalculator {
public double calculateArea(Rectangle rectangle) {
return rectangle.getWidth() * rectangle.getHeight();
}
}
在上面的例子中,有一个Rectangle类表示矩形,有一个AreaCalculator类用于计算矩形的面积。这里违反了开闭原则,如果要添加新的形状(比如圆形),就需要修改AreaCalculator类,这样就打破了对修改关闭的原则。
正例:
public interface Shape {
double calculateArea();
}
public class Rectangle implements 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 void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
}
public class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
public class AreaCalculator {
public double calculateArea(Shape shape) {
return shape.calculateArea();
}
}
在正例中,引入了一个Shape接口,Rectangle和Circle都实现了这个接口。AreaCalculator类不再依赖于具体的形状类,而是依赖于Shape接口。这样,当需要添加新的形状时,只需创建新的类并实现Shape接口,而不需要修改AreaCalculator类,遵循了开闭原则。