设计原则 - 开闭原则

概念

  • 开闭原则的定义: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
  • 类图变化如下:

在这里插入图片描述

在这里插入图片描述

  • 开闭原则的实现总结:接口没变,实现类没变,声明子类来继承实现类,通过继承基类使扩展开放,对修改接口和基类是关闭的,变化的都是应用层的子模块; 越基础的模块变化影响范围越大,越高层的模块变化影响范围越小。
  • 在很多面向对象编程语言中都提供了接口、抽象类等机制,可以通过他们定义系统的抽象层,再通过具体类来进行扩展,如果需要修改系统的行为,无需对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。

源码

GitHubhttps://github.com/Maggieq8324/design_pattern.git


- End -
- 个人学习笔记 -
- 仅供参考 -

posted @ 2021-12-03 11:33  Maggieq8324  阅读(59)  评论(0编辑  收藏  举报