设计模式—开闭原则

1.背景

伯特兰·迈耶一般被认为是最早提出开闭原则这一术语的人,在他1988年发行的《面向对象软件构造》中给出。这一想法认为一旦完成,一个类的实现只应该因错误而修改,新的或者改变的特性应该通过新建不同的类实现。新建的类可以通过继承的方式来重用原类的代码。衍生的子类可以或不可以拥有和原类相同的接口。

梅耶的定义提倡实现继承。具体实现可以通过继承方式来重用,但是接口规格不必如此。已存在的实现对于修改是封闭的,但是新的实现不必实现原有的接口。

2.概念

开闭原则,在面向对象编程领域中,规定"软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的",这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为;它是最基础的设计原则,指导我们建立稳定、灵活的系统。
通俗的讲:
1.对扩展开放,对修改关闭;
2.使程序更易于扩展、维护和升级;

3.开发中如何遵守

系统中的模块、类、方法对他们的提供者应该是开放的,提供者可以对系统进行扩展新的功能。

系统中的模块、类、方法对他们的使用者应该是关闭的,使用者使用这些功能时,不会因为提供方新增了功能而导致使用者也进行相关的修改。

想要达到遵守开闭原则的效果,我们在程序开发时需要使用接口和抽象类。

因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。

4.案例

我们通过一个绘图的功能来演示如何遵守开闭原则;
不遵守开闭原则的代码:

csharp 复制代码
public class DrawShape {
    // TODO 不好的代码
    public void drawView(int type){
        if (1== type){
            System.out.println("圆形");
        }else if (2==type){
            System.out.println("矩形");
        }
    }
}
public class Draw {
    public static void main(String[] args) {
        DrawShape drawShape = new DrawShape();
        // TODO 不好的代码
        // 绘制圆形
        drawShape.drawView(1);
        // 绘制矩形
        drawShape.drawView(2);
    }
}

遵守开闭原则的代码:

csharp 复制代码
/**
 * 画图基础类
 */
public abstract class BaseShape {
    // 画图
    public abstract void drawView();
}

/**
 * 圆形
 */
public class Circle extends BaseShape {
    public void drawView() {
        System.out.println("圆形");
    }
}

/**
 * 矩形
 */
public class Rectangle extends BaseShape {
    public void drawView() {
        System.out.println("矩形");
    }
}

/**
 * 绘制
 */
public class DrawShape {
    public void drawView(BaseShape draw){
        // ... 其他处理
        draw.drawView();
    }
}

public class Draw {
    public static void main(String[] args) {
        DrawShape drawShape = new DrawShape();
        // 绘制圆形
        drawShape.drawView(new Circle());
        // 绘制矩形
        drawShape.drawView(new Rectangle());
    }
}
相关推荐
程序员天天困3 小时前
优雅记录操作日志:从注解到 SpEL 的全链路实践与开源方案对比
java·后端
战血石LoveYY3 小时前
Integer类型超限,导致数据异常
java·算法
CaffeinePro3 小时前
SOLID五大设计原则:重构优雅代码与架构的底层规范
设计模式·架构
乐观的Terry4 小时前
1、为什么要自己造发布系统
java·spring boot·后端·spring cloud·架构
饮茶三千4 小时前
电子保函模板编辑器实战二:HTML→FTL 编译转换的设计与实现
前端·vue.js·设计模式
Kel4 小时前
Node.js 本质:从全脉络视角理解运行时原理
javascript·设计模式·node.js
兰令水4 小时前
hot100【acm版】【2026.7.13打卡-java版本】
java·开发语言·数据结构·算法·leetcode·面试
名字还没想好☜5 小时前
用 Redis + Redisson 实现分布式锁:从踩坑到生产可用
java·redis·分布式·junit·分布式锁·redisson
谙忆5 小时前
图片CDN与边缘优化实战:缓存策略、图片处理型CDN与动态裁剪
java·spring·缓存
ltqvibe5 小时前
怎么让本体语义变成可执行的智能体
java·人工智能·本体语义