设计原则 - 开闭原则
概念
- 开闭原则的定义:Open-Closed Principle,OCP,一个软件实体应当对扩展开放,对修改关闭。
- 开闭原则的中心思想:用抽象构建框架,用实现扩展细节。
- 开闭原则的优点:提高软件系统的可复用性及可维护性
- 实现开闭原则的核心思想:面向抽象编程。
- 一句话理解:软件实现应对扩展开放,对修改关闭
实例
代码实例
- 以慕课网课程举例
ICourse.java
/**
* @Description 课程
* @date Aug 27, 2021
* @Version 1.0
*/
public interface ICourse {
/**
* 课程ID
* @return
*/
Integer getId();
/**
* 课程名称
* @return
*/
String getName();
/**
* 课程价格
* @return
*/
Double getPrice();
}
JavaCourse.java
/**
* @Description Java课程
* @date Aug 27, 2021
* @Version 1.0
*/
public class JavaCourse implements ICourse{
private Integer id;
private String name;
private Double price;
public JavaCourse(Integer id, String name, Double price) {
this.id = id;
this.name = name;
this.price = price;
}
@Override
public Integer getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
@Override
public Double getPrice() {
return this.price;
}
}
Test.java
/**
* @Description 测试类
* @date Aug 27, 2021
* @Version 1.0
*/
public class Test {
public static void main(String[] args) {
ICourse javaCourse1 = new JavaDiscountCourse(1, "Java开发",188d);
System.out.println("课程ID:" + javaCourse1.getId()+ " 课程名称:" + javaCourse1.getName()+ " 课程价格:" + javaCourse1.getPrice());
}
}
- 输出如下:
课程ID:1 课程名称:Java开发 课程价格:150.4
需求变更
- 需求变更:Java课程打⑧折
- 实现该需求可在
ICourse
中新增获取打折价格接口,JavaCourse
实现打⑧折,代码如下: ICourse.java
/**
* 打折价格
* @return
*/
Double getDiscountPrice();
JavaCourse.java
@Override
public Double getDiscountPrice() {
return this.getPrice() * 0.8;
}
- 可以实现,但每一次的扩展都需要变更
ICourse
接口,复用性和维护性较差
开闭原则的实现
JavaDiscountCourse.java
/**
* @Description java折扣
* @date Aug 27, 2021
* @Version 1.0
*/
public class JavaDiscountCourse extends JavaCourse {
public JavaDiscountCourse(Integer id, String name, Double price) {
super(id, name, price);
}
/**
* 原价
* @return
*/
public Double getOriginPrice() {
return super.getPrice();
}
/**
* add 打折场景
* 折扣价
* @return
*/
@Override
public Double getPrice() {
return super.getPrice() * 0.8;
}
}
Test.java
/**
* @Description 开闭原则测试类
* @date Aug 27, 2021
* @Version 1.0
*/
public class Test {
public static void main(String[] args) {
ICourse javaCourse1 = new JavaDiscountCourse(1, "Java开发",188d);
System.out.println("课程ID:" + javaCourse1.getId()+ " 课程名称:" + javaCourse1.getName()+ " 课程价格:" + javaCourse1.getPrice());
JavaDiscountCourse javaCourse2 = (JavaDiscountCourse) javaCourse1;
System.out.println("课程ID:" + javaCourse2.getId()+ " 课程名称:" + javaCourse2.getName()+ " 课程原价:" + javaCourse2.getOriginPrice()+ " 课程折扣价:" + javaCourse2.getPrice());
}
}
- 输出如下:
课程ID:1 课程名称:Java开发 课程价格:150.4
课程ID:1 课程名称:Java开发 课程原价:188.0 课程折扣价:150.4
- 类图变化如下:
- 开闭原则的实现总结:接口没变,实现类没变,声明子类来继承实现类,通过继承基类使扩展开放,对修改接口和基类是关闭的,变化的都是应用层的子模块; 越基础的模块变化影响范围越大,越高层的模块变化影响范围越小。
- 在很多面向对象编程语言中都提供了接口、抽象类等机制,可以通过他们定义系统的抽象层,再通过具体类来进行扩展,如果需要修改系统的行为,无需对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。
源码
GitHub
:https://github.com/Maggieq8324/design_pattern.git