程序员必知!开放封闭原则的实战应用与案例分析

开放封闭原则是面向对象设计中的重要原则之一,它要求软件实体(类、模块、函数等)应该对扩展开放,但对修改关闭。这意味着当需要添加新功能时,不应该修改现有的代码,而是应该通过扩展来实现。这可以通过使用接口、抽象类和多态等机制来实现,从而使系统更加灵活和可扩展。

程序员必知!开放封闭原则的实战应用与案例分析 - 程序员古德

定义

开放封闭原则(Open Closed Principle,简称OCP)是面向开放封闭原则(Open Closed Principle,简称OCP)是面向对象设计中的一个重要原则,它由Bertrand Meyer于1988年提出。该原则主张软件实体(类、模块、函数等等)应该对扩展开放,对修改关闭,这意味着,当需要添加新功能时,我们应该尽量通过扩展已有的代码来实现,而不是修改原有的代码。

该原则的核心思想是,对于已经设计好的软件实体,应该在不修改其源代码的情况下,通过扩展来增加新的功能或行为。换句话说,我们应该尽可能地保持软件实体的稳定性和可靠性,而不是通过修改源代码来适应新的需求。在实现开放封闭原则时,需要注意以下几点:

  1. 对扩展开放:当需要添加新功能时,应该通过扩展现有的类或模块来实现,而不是修改现有的代码。这可以通过使用接口、抽象类和多态等机制来实现。
  2. 对修改关闭:当添加新功能时,不应该修改现有的代码。如果必须修改现有的代码,那么这种修改应该是有计划、有目的的,并且应该尽量避免对其他部分的代码产生影响。
  3. 抽象化设计:通过抽象化设计,可以将具体的实现细节隐藏在抽象接口之后,从而保护现有的代码不被修改。同时,抽象化设计也可以提高代码的可重用性和可维护性。
  4. 模块化设计:通过模块化设计,可以将系统划分为多个独立的模块,每个模块都有明确的职责和功能。这样可以降低系统的耦合度,提高系统的可维护性和可扩展性。

程序员必知!开放封闭原则的实战应用与案例分析 - 程序员古德

代码案例

假设我们正在开发一个电商系统,其中包括一个订单处理模块,该模块负责处理用户的订单,包括计算订单金额、生成订单号、发送订单确认邮件等功能。

首先,我们来看一个不符合开放封闭原则的设计,代码如下:


/**
 * @版权 Copyright by 程序员古德 <br>
 * @创建人 程序员古德 <br>
 * @创建时间 2023/12/15 16:37 <br>
 */

// 不符合开放封闭原则的设计  
  
public class OrderProcessor {  
    public void processOrder(Order order) {  
        // 计算订单金额  
        double amount = calculateOrderAmount(order);  
          
        // 生成订单号  
        String orderNumber = generateOrderNumber();  
          
        // 发送订单确认邮件  
        sendOrderConfirmationEmail(order, amount, orderNumber);  
          
        // 其他订单处理逻辑...  
    }  
      
    private double calculateOrderAmount(Order order) {  
        // 计算订单金额的逻辑  
        return 0.0;  
    }  
      
    private String generateOrderNumber() {  
        // 生成订单号的逻辑  
        return null;  
    }  
      
    private void sendOrderConfirmationEmail(Order order, double amount, String orderNumber) {  
        // 发送订单确认邮件的逻辑  
    }  
}

在上面的代码中,OrderProcessor类负责处理订单的全部逻辑,包括计算金额、生成订单号、发送确认邮件等。如果我们需要添加新的功能,比如添加优惠券处理逻辑,就需要修改OrderProcessor类的代码,这样不符合开放封闭原则,每次添加新功能都需要修改已有代码,会增加系统的维护成本,并且容易引入错误。

为了解决这个问题,我们可以使用开放封闭原则进行改进,我们可以将订单处理的不同功能抽象为不同的接口,比如OrderAmountCalculatorOrderNumberGeneratorOrderConfirmationEmailSender等。然后,我们可以实现这些接口来提供具体的功能实现,这样,当需要添加新功能时,只需要扩展相应的接口,而不需要修改已有的代码,下面是改进后的代码:


/**
 * @版权 Copyright by 程序员古德 <br>
 * @创建人 程序员古德 <br>
 * @创建时间 2023/12/15 16:37 <br>
 */

// 符合开放封闭原则的设计  
  
public interface OrderAmountCalculator {  
    double calculate(Order order);  
}  
  
public interface OrderNumberGenerator {  
    String generate();  
}  
  
public interface OrderConfirmationEmailSender {  
    void send(Order order, double amount, String orderNumber);  
}  
  
public class SimpleOrderAmountCalculator implements OrderAmountCalculator {  
    @Override  
    public double calculate(Order order) {  
        // 计算订单金额的逻辑  
        return 0.0;  
    }  
}  
  
public class SimpleOrderNumberGenerator implements OrderNumberGenerator {  
    @Override  
    public String generate() {  
        // 生成订单号的逻辑  
        return null;  
    }  
}  
  
public class SimpleOrderConfirmationEmailSender implements OrderConfirmationEmailSender {  
    @Override  
    public void send(Order order, double amount, String orderNumber) {  
        // 发送订单确认邮件的逻辑  
    }  
}  
  
public class OrderProcessor {  
    private OrderAmountCalculator orderAmountCalculator;  
    private OrderNumberGenerator orderNumberGenerator;  
    private OrderConfirmationEmailSender orderConfirmationEmailSender;  
      
    public OrderProcessor(OrderAmountCalculator orderAmountCalculator, OrderNumberGenerator orderNumberGenerator, OrderConfirmationEmailSender orderConfirmationEmailSender) {  
        this.orderAmountCalculator = orderAmountCalculator;  
        this.orderNumberGenerator = orderNumberGenerator;  
        this.orderConfirmationEmailSender = orderConfirmationEmailSender;  
    }  
      
    public void processOrder(Order order) {  
        double amount = orderAmountCalculator.calculate(order);  
        String orderNumber = orderNumberGenerator.generate();  
        orderConfirmationEmailSender.send(order, amount, orderNumber);  
        // 其他订单处理逻辑...  
    }  
}  

在上面的代码中,我们将订单处理的不同功能抽象为了不同的接口,并且提供了相应的实现类,这样,当需要添加新功能时,只需要扩展相应的接口,并提供一个新的实现类即可,比如,如果我们想要添加优惠券处理逻辑,可以创建一个实现了OrderAmountCalculator接口的CouponOrderAmountCalculator类,然后在创建OrderProcessor对象时传入这个新的实现类即可。这种方式符合开放封闭原则,可以在不修改已有代码的情况下扩展系统的功能。同时,由于使用了接口进行抽象,代码的可读性和可维护性也得到了提高,这种方式可以使我们的系统更加灵活和可扩展。

核心总结

程序员必知!开放封闭原则的实战应用与案例分析 - 程序员古德

开封封闭原则(Open-Closed Principle,OCP)是面向对象设计的五个基本原则之一,它指导我们设计模块时应尽量使其对扩展开放,对修改关闭,这意味着我们可以增加新的功能,而不需要改动已有的代码。

优点:一是提高软件的可维护性,因为修改原有代码可能会引入新的错误;二是有利于团队协作,每个人都可以在不干扰其他人的情况下添加新功能;三是有利于复用,因为每个类或模块只做一件事,所以更容易找到可以复用的代码。

缺点:一是过度设计,如果预设了过多的扩展点,可能导致代码过于复杂;二是可能增加系统的耦合度,因为为了满足开封封闭原则,可能需要引入一些抽象类或接口。

使用建议:在实际开发中,我们应该根据项目需求和规模来权衡是否严格遵循开封封闭原则。对于小型项目或者短期内不会频繁变动的项目,可能不需要过度设计。而对于大型项目或者需要长期维护的项目,遵守开封封闭原则则更为重要。同时,我们也应该注意避免过度设计和增加系统耦合度的问题,可以通过重构和优化代码结构来解决这些问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/259013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux上随机输出谚语的程序fortune

概要&#xff1a; Linux上有一个随机输出谚语的程序叫fortune 手册对它的描述是&#xff1a;输出一个随机的、充满希望的、有趣的谚语 本篇所用的系统是Ubuntu22.04 一、fortune的安装 sudo apt install fortune-mod 二、fortune的使用 1、示例一 这个谚语是什么意思啊…

机器学习与深度学习傻傻分不清?快来!

导读&#xff1a;本文探讨机器学习和深度学习之间的关键区别和相互联系&#xff0c;目的是为大家提供一个清晰的框架&#xff0c;帮助大家理解这两种技术的特点、应用场景以及选择适当方法的依据。&#xff08;理论辨析&#xff0c;无实践代码&#xff0c;放心食用&#xff09;…

CEC2013(python):五种算法(GA、WOA、GWO、DBO、HHO)求解CEC2013(python代码)

一、五种算法简介 1、遗传算法算法GA 2、鲸鱼优化算法WOA 3、灰狼优化算法GWO 4、蜣螂优化算法DBO 5、哈里斯鹰优化算法HHO 二、5种算法求解CEC2013 &#xff08;1&#xff09;CEC2013简介 参考文献&#xff1a; [1] Liang J J , Qu B Y , Suganthan P N , et al. Prob…

STM32内部是怎么工作的

STM32是怎么工作的 1 从孩子他妈说起2 早期计算机的组成2.1 五大元件&#xff08;1&#xff09;第一个出场的是电容元件&#xff08;2&#xff09;第二个出场的是二极管&#xff08;3&#xff09;第三个出场的是电阻元件&#xff08;4&#xff09;第四个出场的是电感&#xff0…

【论文简述】Learning Depth Estimation for Transparent and Mirror Surfaces(ICCV 2023)

一、论文简述 1. 第一作者&#xff1a;Alex Costanzino 2. 发表年份&#xff1a;2023 3. 发表期刊&#xff1a;ICCV 4. 关键词&#xff1a;深度感知、立体匹配、深度学习、分割、透明物体、镜子 5. 探索动机&#xff1a;透明或镜面(ToM)制成的材料&#xff0c;从建筑物的玻…

RabbitMQ入门指南(三):Java入门示例

专栏导航 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、AMQP协议 1.AMQP 2.Spring AMQP 二、使用Spring AMQP实现对RabbitMQ的消息收发 1.案例准备阶段 2.入门案例&#xff08;无交换机&#xff09; 3.任务模型案例&#xff08;Work Queues&#xff0…

文献速递:生成对抗网络医学影像中的应用——用于生成前列腺MR-only影像治疗剂量规划的合成CT的深度学习模型:多中心研究

文献速递&#xff1a;生成对抗网络医学影像中的应用——用于生成前列腺MR-only影像治疗剂量规划的合成CT的深度学习模型&#xff1a;多中心研究 本周给大家分享文献的主题是生成对抗网络&#xff08;Generative adversarial networks, GANs&#xff09;在医学影像中的应用。文…

Chatgpt如何多人使用?如何防止封号?

时下火爆年轻人的AI技术当属于Chatgpt&#xff0c;但他是一把双刃剑&#xff0c;使用它给我们带来便利的同时&#xff0c;也可能会带来隐患&#xff0c;因此我们需要科学使用AI技术。 本文将针对备受关注的Chatgpt如何多人共享使用&#xff1f;如何防止封号&#xff0c;为你带…

python堆-完全二叉树--完全解读

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于海外某世界知名高校就读计算机相关专业。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。…

PHP 读取excel输入为HTML

目录 介绍 安装扩展 读取excel文件 输入为html 保存到文件 总结 介绍 以前都是使用phpexcel&#xff0c;不过已经不再更新了&#xff0c; 不过不用担心还可以使用phpspreadsheet来替代它进行操作。 PHPSpreadsheet-在PHP中读取、创建和编写电子表格文档-电子表格引擎。…

SpringBoot代码混淆与反混淆加密工具详解

目录 反编译 混淆 正文 一共就两步&#xff0c;无需源码&#xff0c;直接对ipa文件进行混淆加密 打开要处理的IPA文件 设置签名使用的证书和描述文件 开始ios ipa重签名 简单就是把代码跑一哈&#xff0c;然后我们的代码 .java文件 就被编译成了 .class 文件 反编译 就是…

高精度地图定位模块技术规范

目 录 1 概述................................................................................................... 5 1.1 适用范围...................................................................................... 5 1.2 规范性引用文件....................…

Multimodal Chain-of-Thought Reasoning in Language Models语言模型中的多模态思维链推理

Abstract 大型语言模型 (LLM) 通过利用思维链 (CoT) 提示生成中间推理链作为推断答案的基本原理&#xff0c;在复杂推理方面表现出了令人印象深刻的性能。然而&#xff0c;现有的 CoT 研究主要集中在语言情态上。我们提出了 Multimodal-CoT&#xff0c;它将语言&#xff08;文本…

MyBatis-Plus(一):根据指定字段更新或插入

根据指定字段更新或插入 1、概述2、实现方式2、总结 1、概述 MyBatis-Plus中提供了一个saveOrUpdate()方法&#xff0c;默认情况下可以根据主键是否存在进行更新或插入操作&#xff0c;但是实际场景中&#xff0c;根据指定字段进行更新或插入的情况也非常多见&#xff0c;今天…

MySQL——表的增删查改

目录 一.Create&#xff08;创建&#xff09; 1.单行数据 全列插入 2.多行数据 指定列插入 3.插入否则更新 4. 替换 二.Retrieve&#xff08;读取&#xff09; 1. select 列 查询 2.where 条件 3.结果排序 4.筛选分页结果 三.Update &#xff08;修改&#xff09;…

DDR4 设计概述以及分析仿真案例(硬件学习)

引言&#xff1a;随着计算机&#xff0c;服务器的性能需求越来越高&#xff0c;DDR4开始应用在一些高端设计中&#xff0c;然而目前关于DDR4的资料非常少&#xff0c;尤其是针对SI(信号完整性)部分以及相关中文资料&#xff0c;另外一方面&#xff0c;DDR4的高速率非常容易引起…

【论文笔记】MCANet: Medical Image Segmentation withMulti-Scale Cross-Axis Attention

医疗图像分割任务中&#xff0c;捕获多尺度信息、构建长期依赖对分割结果有非常大的影响。该论文提出了 Multi-scale Cross-axis Attention&#xff08;MCA&#xff09;模块&#xff0c;融合了多尺度特征&#xff0c;并使用Attention提取全局上下文信息。 论文地址&#xff1a…

融云观察:给 ChatGPT 加上声音和脸庞,AI 社交的多模态试验

&#xff08;&#x1f446;点击获取行业首款《社交泛娱乐出海作战地图》&#xff09; 如果将短剧的爆火简单粗暴地归因为剧情上头、狗血反转和精妙卡点&#xff0c;那 GenAI 世界这一年来可以说是一部短剧 Live Show。关注【融云全球互联网通信云】了解更多 这厢 Open AI 宫斗…

别再唱衰Python了,未来十年Python的“霸榜”地位依旧!

直接说结论&#xff01;不管唱反调的人怎么唱衰&#xff0c;Python 在下一个十年仍然十分重要&#xff0c;并且依旧会与时俱进。 我们都知道 Python 是一门了不起的编程语言&#xff0c;它改变了编程的游戏规则&#xff0c;将编程的格局提升到了一个完全不同的层次。 Python 的…

【C++初阶】学习string类的模拟实现

目录 前言&#xff1a;一、创建文件和类二、实现string类2.1 私有成员和构造函数2.2 析构函数2.3 拷贝构造函数2.3.1 写法12.3.2 写法2 2.4 赋值重载函数2.4.1 写法12.4.2 写法2 2.5 迭代器遍历访问2.6 下标遍历访问2.7 reserve2.8 resize2.9 判空和清理2.10 尾插2.10.1 尾插字…
最新文章