定义
一个软件实体,如类和函数应该对扩展开放,对修改关闭。是软件设计中最基础的设计原则,它指导我们如何简历稳定灵活的系统,例如我们版本更新,不修改代码可以增加新功能。实现开闭原则的核心思想是面向抽象编程而不是面向具体的实现
优点
提高软件系统的可复用性和可维护性
代码案例
有如下代码,我们有一个接口(ICourer)定义了获取id、名称、价格的方法,有实现类(Course)继承自这个接口,有一个测试方法类(Test),可以打印出信息
ICourse接口:
public interface ICourse {
Integer getId(); //获取课程id
String getName(); //获取课程名称
Double getPrice(); //获取课程价格
}
Course类:
public class Course implements ICourse{
private Integer id;
private String name;
private Double price;
public Course(Integer id, String name, Double price) {
this.id = id;
this.name = name;
this.price = price;
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
public Double getPrice() {
return this.price;
}
}
Test类:
public class Test {
public static void main(String[] args) {
ICourse course = new Course(1,"java入门",299d);
System.out.println("课程id:"+course.getId()+",课程名称:"+course.getName()+",课程价格:"+course.getPrice());
}
}
此时我们运行Test,控制台会有如下输出,没有任何问题
课程id:1,课程名称:java入门,课程价格:299.0
新需求
我们现在要对课程进行打折活动,全场9折,或者满200打9折满300打8折等
- 我们可以在接口中定义一个方法如 getDiscountPrice,然后实现类实现此方法。这样做不但修改了接口,而且还修改了实现类,假如实现类有很多个,那我们将修改很多个类,违反了开闭原则
- 仅在实现类中增加 getDiscountPrice 方法。这样做就跟上面的效果一样了
最佳方案
新建一个课程打折类(DiscountCourse),继承自课程类(Count),并在里面定义具体的打折方法
这种方案的优点是,我们无需修改底层的类(Course),通过新增类去新增功能,仅在上端调用的地方(Test类)做出修改,就可以实现需求。符合对修改关闭,对扩展开放的原则。
DiscountCourse:
public class DiscountCourse extends Course{
public DiscountCourse(Integer id, String name, Double price) {
super(id, name, price);
}
public Double getDiscountPrice(){
//这里写打折的逻辑
return super.getPrice() * 0.8;
}
}
修改Test类:
public class Test {
public static void main(String[] args) {
ICourse iCourse = new DiscountCourse(1,"java入门",299d);
DiscountCourse course = (DiscountCourse)iCourse; //这
System.out.println("课程id:"+course.getId()+",课程名称:"+course.getName()+",课程原价:"+course.getPrice()+",打折后价格:"+course.getDiscountPrice());
}
}
此时运行Test,会有如下输出
课程id:1,课程名称:java入门,课程原价:299.0,打折后价格:239.20000000000002