设计模式—开闭原则

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());
    }
}
相关推荐
夹芯饼干几秒前
虚拟机指令第六节
java·linux·服务器
A_aspectJ26 分钟前
【Java基础开发】基于 Java Swing +MySQL + JDBC 版实现图书管理系统
java·开发语言·mysql
TE-茶叶蛋26 分钟前
Spring最核心扩展点:BeanPostProcessor
java·后端·spring
Mr.456727 分钟前
SpringBoot多模块依赖冲突排查与架构优化实战(避坑指南)
java·spring boot·架构
学术阿凡提28 分钟前
Spring Boot 优雅实现异步调用:从入门到自定义线程池与异常处理
java·数据库·算法
我是无敌小恐龙43 分钟前
Java SE 零基础入门Day06 方法重载+Debug调试+String字符串全套API详解(超全干货)
java·开发语言·人工智能·python·transformer·无人机·量子计算
xiaoye37081 小时前
java接口文档工具 swagger2和swagger3对比
java·服务器·前端
三维频道1 小时前
工业级三维扫描实测:汽车灯具复杂结构件的全尺寸 3D 测量方案分析
java·人工智能·python·数码相机·3d·汽车·汽车轻量化制造
tongyiixiaohuang1 小时前
基于轻易云的数据集成,实现企业系统间灵活对接
java·前端·数据库
码农飞哥1 小时前
从Java后端到AI应用开发,我这两年做了什么
java·开发语言·人工智能