设计模式之开闭原则

开闭原则

本片文章在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("...");
    }
}
相关推荐
倔强的石头_25 分钟前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
阿星AI工作室7 小时前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦1 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
jiayou641 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤2 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区3 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1773 天前
《从零搭建NestJS项目》
数据库·typescript
加号34 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏4 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐4 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端