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


    面向对象设计原则之开-闭原则
    面向对象设计原则之里式替换原则
    面向对象设计原则之依赖倒置原则
    面向对象设计原则之单一职责原则

    定义

    开闭原则(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. 提高软件可维护性:遵循开闭原则的软件,其稳定性和延续性强,从而易于扩展和维护。

    实现方法

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

    代码示例

    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

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

    在这里插入图片描述
    写一个main方法测试类,初始化一个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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输出结果如下

    课程ID:1
    课程名称:java
    课程价格:80.0

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

    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    写一个main方法测试类,初始化一个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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果如下:

    课程ID:1
    课程名称:java
    课程原价:100.0
    课程折扣价:80.0

  • 相关阅读:
    【Unity】XML文件的解析和生成
    subject may not be empty[Git]
    LaTex常用技巧6:矩阵编写总结
    听书项目总结
    企微SCRM营销平台MarketGo-ChatGPT助力私域运营
    42-接雨水
    蓝牙核心规范(V5.4)10.3-BLE 入门笔记之BIS篇
    spring-cloud-gateway服务网关学习
    数据结构与算法C语言版学习笔记(6)-树、二叉树、赫夫曼树
    Java 反射机制详解
  • 原文地址:https://blog.csdn.net/quyingzhe0217/article/details/133746978