设计模式之开闭原则

开闭原则

本片文章在springBoot3,jdk21下测试通过

1.开闭原则概述

1.定义:对扩展开放,对修改关闭

  • 对扩展开放:意味着当系统需要增加新的功能时,可以在不修改现有代码的基础上进行扩展。通过提供抽象层和扩展点来实现新功能,而不是直接修改原有代码
  • 对修改关闭:已经完成并测试过的软件实体(类、模块、函数等)应该尽量避免被修改。一旦软件的一个部分被视为稳定且工作正常,就不应该对其源码做出改动以适应新的需求

2.开闭原则到底解决了什么问题?

  • 应对需求变化:在软件开发过程中,产品经理的需求是难以完全预见的,因此代码需要具备良好的适应性来应对需求变更。开闭原则要求已有的代码结构对新的功能需求能够通过扩展而非修改来实现,从而避免了因直接修改源码带来的风险
  • 降低耦合度:遵循开闭原则的设计倾向于使用抽象类、接口等机制来定义行为,并通过子类或策略等方式进行具体实现。这种方式降低了不同组件之间的耦合度,使得新添加的功能模块不会直接影响到原有系统的核心结构
  • 提高复用性:通过提供稳定的抽象层和明确的扩展点,代码可以更方便地被复用。新增加的功能可以通过增加新的类或者模块来完成,而无需改动现有稳定的部分
  • 减少潜在错误:直接修改已经经过充分测试和验证的代码容易引入新的bug。开闭原则强调不对原有代码进行修改,从而减少了由于修改引发的潜在错误
  • 简化维护:当系统的架构基于开闭原则设计时,维护工作通常会变得更加简单和可控,因为每个功能都是独立且易于替换的,而不是硬编码在整个系统中

3.用代码来列举一个案例

需求:我们有一个计算器类,最初只支持加法操作

大多数程序员都会使用的方式,也就是未遵循开闭原则的代码,如下:

java 复制代码
public class JiSuanQi {
    public double init(String operation, double num1, double num2) {
        if ("add".equals(operation)) {
            return num1 + num2;
        } else {
            throw new IllegalArgumentException("错误");
        }
    }
}

更改需求:我们需要添加减法操作

java 复制代码
public class JiSuanQi {
    public double init(String operation, double num1, double num2) {
        if ("add".equals(operation)) {
            return num1 + num2;
        } else if ("subtract".equals(operation)) { // 新增代码
            return num1 - num2; // 新增代码
        } else {
            throw new IllegalArgumentException("错误");
        }
    }
}

现在采用遵循开闭原则的例子

java 复制代码
public interface Operation {
    double perform(double num1, double num2);
}

public class Addition implements Operation {
    @Override
    public double perform(double num1, double num2) {
        return num1 + num2;
    }
}

public class Subtraction implements Operation {
    @Override
    public double perform(double num1, double num2) {
        return num1 - num2;
    }
}

需求更改:添加一个乘法的方法

java 复制代码
// 当需要添加新的运算如乘法时
public class Multiplication implements Operation {
    @Override
    public double perform(double num1, double num2) {
        return num1 * num2;
    }
}

2.开闭原则使用场景

1.支付方式中的使用

代码类似于标题一中遵循开闭原则的例子,此处就省略

2.数据源切换

博主曾经写过一篇关于mybatis动态切换数据源的文章有兴趣的博主自行阅读,连接如下:https://blog.csdn.net/weixin_44702984/article/details/134855131?spm=1001.2014.3001.5502
链接直达

下面的案例只是提供思路,代码可以自行完成

1.定义数据访问层接口

java 复制代码
public interface DataAccess {
    // 获取链接
    void connect();
    // 执行SQL
    void executeQuery(String query);
    // 其他通用方法...
}

2.接口实现类

java 复制代码
public class MySQLDataAccess implements DataAccess {
    // 实现与MySQL相关的connect, executeQuery等方法...
}

public class OracleDataAccess implements DataAccess {
    // 实现与Oracle相关的connect, executeQuery等方法...
}

3.主程序使用DataAccess接口

java 复制代码
public class Application {
    private DataAccess dataAccess;
    
    public void setDataAccess(DataAccess da) {
        this.dataAccess = da;
    }
    
    public void performDatabaseOperation() {
        dataAccess.connect();
        dataAccess.executeQuery("...");
    }
}
相关推荐
余槐i4 小时前
PostgreSQL 函数索引报错 must be immutable:3种绕法与代价
数据库·后端·sql·postgresql·性能优化
数据库小学妹4 小时前
PostgreSQL表膨胀怎么办?autovacuum清不动的根因与排查命令
数据库·postgresql·表膨胀·mvcc·数据库运维
mister_guo5 小时前
MySQL-1267错误:排序规则冲突的原因与解决方案
数据库·mysql
骇客野人5 小时前
在麒麟操作系统上 分别安装 jdk1.8, 达梦数据库,redis ,memcache 的操作实施方案和步骤
数据库·redis·memcached
美狐美颜SDK开放平台7 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
花间相见8 小时前
【计算基础|MySQL01】【上手】安装连接、数据类型与建库建表
数据库·后端
花间相见8 小时前
【计算基础|MySQL02】【上手】SQL 增删改查
数据库·后端
ITxiaobing20239 小时前
IP 库与 AppsFlyer 国家/地区数据不一致,如何系统地对账?
数据库·网络协议·tcp/ip
这个DBA有点耶9 小时前
从时间到语义:时序数据库与向量数据库的核心机制、选型与多模融合趋势
数据库·mysql·架构
对空六课9 小时前
RFM分层边界变化的回溯计算
大数据·服务器·前端·数据库·人工智能·算法·数据分析