面向对象设计原则之开-闭原则

目录

定义

开闭原则(Open Closed Principle, OCP)由勃兰特·梅耶(Bertrand Meyer)提出,他在 1988 年的著作《面向对象软件构造》(Object Oriented Software Construction)中提出:软件实体应当对扩展开放,对修改关闭(Software entities should be open for extension,but closed for modification),这就是开闭原则的经典定义。

这里的软件实体包括以下几个部分:

  1. 项目中划分出的模块
  2. 类与接口
  3. 方法

开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。

作用

开闭原则是面向对象程序设计的终极目标,它使软件实体拥有一定的适应性和灵活性,但同时具备稳定性和延续性。具体作用如下:

  1. . 对软件测试的影响:如果软件遵循开闭原则,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的逻辑未修改,原有的测试代码逻辑也仍然能够正常运行。
  2. 提高代码可复用性:粒度越小,可复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。
  3. 提高软件可维护性:遵循开闭原则的软件,其稳定性和延续性强,从而易于扩展和维护。

实现方法

通过"抽象约束、封装变化"来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在具体的实现类中;用抽象构建框架,用实现类实现具体细节。

代码示例

java 复制代码
package will.tools.design;
 
/**
 * 定义个课程接口,定义公共行为方法
 * getName() 课程名称
 * getPrice() 课程价格
 */
public interface ICourse {
    Integer getId();
 
    String getName();
 
    Double getPrice();
}

package will.tools.design;
 
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 id;
    }
 
    @Override
    public String getName() {
        return name;
    }
 
    @Override
    public Double getPrice() {
        return price;
    }
 
    @Override
    public String toString() {
        return "课程ID:" + getId() +
                "\n课程名称:" + getName() +
                "\n课程价格:" + getPrice();
    }
}

定义课程接口ICourse,定义公共方法,获取课程名称、价格等;实现Java课程类JavaCourse,实例化具体课程对象;当需求发生变化,如Java课程价格发生变化(8折)时,我们可以在Java实现类中修改,如下图:

写一个main方法测试类,初始化一个java课程并输出

java 复制代码
package will.tools.design;
 
public class CourseTest {
    public static void main(String[] args){
    
        ICourse course = new JavaCourse(1,"java",100d);
        System.out.println(course.toString());
    }
}

输出结果如下

课程ID:1

课程名称:java

课程价格:80.0

但此时,其实已经违反了开闭原则,因为直接对业务需求进行了修改。即每次使用不同的折扣时,都需要修改一次JavaCourse类频繁修改原有的逻辑,在复杂业务中非常容易出现问题。这时,我们可以对修改关闭,即原JavaCourse中不要修改,而是采用扩展的方式,通过继承类,实现需求细节的修改,让我们的代码风险可控。实现如下:

java 复制代码
package will.tools.design;
 
public class JavaDiscountCourse extends JavaCourse {
    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }
 
    public Double getDiscountPrice() {
        return super.getPrice() * 0.8;
    }
 
    @Override
    public String toString() {
        return "课程ID:" + getId() +
                "\n课程名称:" + getName() +
                "\n课程原价:" + getPrice() +
                "\n课程折扣价:" + getDiscountPrice();
    }
}

写一个main方法测试类,初始化一个java课程并输出

java 复制代码
package will.tools.design;
 
public class CourseTest {
    public static void main(String[] args){
    
        ICourse course2 = new JavaDiscountCourse(1,"java",100d);
        System.out.println(course2.toString());
    }
}

结果如下:

课程ID:1

课程名称:java

课程原价:100.0

课程折扣价:80.0

相关推荐
蜡笔小新..11 小时前
【设计模式】软件设计原则——开闭原则&里氏替换&单一职责
java·设计模式·开闭原则·单一职责原则
niech_cn7 天前
超详细超实用!!!AI编程之cursor编写设计模式开闭原则实例(四)
设计模式·ai编程·开闭原则
丶白泽16 天前
重修设计模式-设计原则
设计模式·接口隔离原则·依赖倒置原则·开闭原则
蔚一21 天前
Java设计模式—面向对象设计原则(一) ----->开闭原则OCP(完整详解,附有代码+案例)
java·后端·设计模式·intellij-idea·开闭原则
MogulNemenis1 个月前
符合开闭原则的设计模式
设计模式·bash·开闭原则
要记得喝水1 个月前
软件设计原则之开闭原则
windows·c#·.net·visual studio·开闭原则
认真的小羽❅1 个月前
设计模式 -- 七大原则(五)-- 开闭原则
设计模式·开闭原则
海的宇宙2 个月前
C#:具体类=>抽象类=>接口的变化过程详解
开发语言·面试·c#·抽象工厂模式·接口隔离原则·开闭原则
A22743 个月前
零——七大设计原则
接口隔离原则·依赖倒置原则·里氏替换原则·开闭原则·迪米特法则·合成复用原则·单一职责原则
一大颗萝卜3 个月前
【原创实现 设计模式】Spring+策略+模版+工厂模式去掉if-else,实现开闭原则,优雅扩展
java·spring·设计模式·简单工厂模式·策略模式·模板方法模式·开闭原则