首页 > 其他分享 >设计原则--开闭原则OCP

设计原则--开闭原则OCP

时间:2024-01-25 15:01:05浏览次数:18  
标签:原则 -- 代码 开闭 修改 模块 组件 OCP

目录


简介

开闭原则(Open-Closed Principle,OCP)是软件工程中的一个重要设计原则,它指出软件实体(类、模块、函数等)应该对扩展开放,对修改关闭

开闭原则的核心思想是,在设计一个软件系统时,应该尽量保持其稳定性和可扩展性。当需要对系统进行扩展或修改时,应该通过添加新的功能而不是修改现有的代码来实现。这样可以降低系统的复杂度,提高代码的可维护性和复用性。

具体来说,开闭原则要求在设计软件系统时,将其划分为一系列相对独立的模块或组件,并且每个模块或组件都应该具有明确的职责和接口。当需要对系统进行扩展时,可以通过添加新的模块或组件来实现,而不需要修改现有的模块或组件。

开闭原则的好处包括:

  1. 提高代码的可维护性:当代码遵循开闭原则时,对系统的修改只会影响到少数几个模块或组件,从而降低了维护的难度。

  2. 增强代码的复用性:由于每个模块或组件都具有明确的职责和接口,因此可以在不同的项目中复用这些模块或组件,提高了开发效率。

  3. 降低系统的复杂度:通过将系统划分为多个独立的模块或组件,可以降低系统的复杂度,使其更容易理解和维护。

  4. 提高系统的可扩展性:遵循开闭原则可以使系统更容易进行扩展,从而满足不断变化的业务需求。

总之,开闭原则是软件设计中的一个重要原则,它可以帮助开发者构建更加稳定、可维护和可扩展的软件系统。


如何遵守?

在实际项目中,有效地遵循开闭原则可以采取以下几个方法:

  1. 抽象和封装:使用抽象类和接口来定义模块或组件的公共接口,将具体的实现细节封装在内部。这样可以使系统更加灵活,便于扩展和修改。

  2. 代码复用:利用代码复用的原则,尽量使用现有的代码和库,避免重复编写相同的功能。通过复用代码,可以减少修改的范围,提高系统的稳定性。

  3. 模块划分:将系统划分为多个独立的模块或组件,每个模块或组件具有明确的职责和接口。这样可以降低系统的复杂度,便于维护和扩展。

  4. 设计模式:使用一些设计模式,如策略模式、观察者模式、装饰器模式等,可以更好地遵循开闭原则。这些模式提供了一种封装变化和扩展的方式,使系统更加灵活和可维护。

  5. 测试驱动开发:采用测试驱动开发(Test-Driven Development,TDD)的方法,编写测试用例来验证系统的功能。通过编写测试用例,可以在修改代码时确保系统的正确性,并减少回归问题的出现。

  6. 持续集成(Continuous integration,简称CI)和自动化测试:利用持续集成工具和自动化测试框架,频繁地进行集成和测试。这样可以及时发现问题,保证系统的稳定性和可靠性。

  7. 团队协作和沟通:在项目开发过程中,团队成员之间应该保持良好的沟通和协作。共同理解开闭原则的重要性,并在设计和实现过程中共同努力遵循这一原则。

遵循开闭原则需要在软件开发的整个过程中始终关注可扩展性和可维护性。通过合理的设计、抽象、封装和测试,可以有效地遵循开闭原则,构建更加灵活和可持续发展的软件系统。


反例

以下是一个车辆价格计算的示例代码,它违反了开闭原则:

public class Car {
    private String brand;
    private double price;
    
    // 获取车辆品牌
    public String getBrand() {
        return brand;
    }
    
    // 设置车辆品牌
    public void setBrand(String brand) {
        this.brand = brand;
    }
    
    // 获取车辆价格
    public double getPrice() {
        return price;
    }
    
    // 设置车辆价格
    public void setPrice(double price) {
        this.price = price;
    }
    
    // 对车辆打八折的示例
    public double getPrice() {
        return price * 0.8;
    }
}

上述代码中,getPrice()方法被重写以提供车辆打八折的功能。但是,这种修改方式违反了开闭原则,因为它直接修改了源代码。如果后续需要对其他车辆类型应用不同的折扣,就需要再次修改getPrice()方法,这可能会导致代码的可读性和可维护性降低。

标签:原则,--,代码,开闭,修改,模块,组件,OCP
From: https://www.cnblogs.com/yubo-guan/p/17987176

相关文章

  • 【习题】3.1
    [T030101]证明初值问题\(\frac{\mathrmdy}{\mathrmdx}=x^2+e^{-y^2},\y(0)=0\)的解\(y=\varphi(x)\)在\([0,\frac12]\)上存在,且当\(x\in[0,\frac12]\)时,\(|\varphi(x)|\le1\).    证设\(f(x,y)=x^2+e^{-y^2}\),取矩形区域\(R:\|x|\le1,\|y|\le......
  • 货币系统
    其实这道题目如果加上证明有蓝的观察样例的解释,我们可以猜测一个结论:最终的货币面值一定由最初的货币面值的子集构成,而且没有选择的货币面值是可以被选择的货币面值线性表示的所以我们马上就得到了一个DP算法,在考场上实在证不出来直接写就好了:1、将\(a\)数组从小到大排序2、最......
  • WorkFlow,Process,Job,Task各详细解释和他们的区别
    来自你的消息:请详细解释WorkFlow,Process,Job,Task各详细解释和他们的区别来自WeTabAI的消息:当谈到工作流程(Workflow),流程(Process),任务(Job)和任务(Task)时,它们在企业管理和信息技术领域中有不同的含义和用法。下面是它们的详细解释和区别:工作流程(Workflow):工作流程是一系列有序的......
  • 17、std::move和移动语义详解
    概述std::move是C++标准库中的一个函数模板,用于将一个左值(左值引用)转化为右值引用,从而实现移动语义。移动语义是一种可以将资源(如内存)从一个对象转移到另一个对象的方式,而不是进行资源的复制。移动操作通常比复制操作更高效,对于大型的对象(如容器、字符串等)可以带来很大的......
  • 进程间的通信(管道)
    (一)引入借助于消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取出。这种通信方式是非阻塞的,即发送进程不需要等待接收进程的响应即可继续执行。multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的进程间通信(IPC)方式二:管道(不推荐使用,了解即可......
  • 进程间通信(队列和生产消费模型)
    (一)引入(1)什么是进程间的通信IPC进程间通信(Inter-ProcessCommunication,IPC)是指两个或多个进程之间进行信息交换的过程它是一种计算机编程技术,用于在不同的进程之间共享数据和资源(2)如何实现进程间通信借助于消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取......
  • IO模型
    (一)IO模型简介目前我们眼睛的IO都是基于网络IO的Stevens在文章中一共比较了五种IOModel:blockingIO阻塞IO模型nonblockingIO非阻塞IO模型IOmultiplexingIO多路复用模型signaldrivenIO---(忽略)asynchronousIO异步IO模型由signaldrivenIO(信号驱动IO)在实......
  • 协程操作
    基于async和await关键字的协程可以实现异步编程,这也是目前Python异步相关的主流技术。(一)asyncio模块asyncio模块是Python中实现异步的一个模块,该模块在Python3.4的时候发布asycnio和await关键字在Python3.5引入(二)事件循环事件循环就是可以把它当作一个while循环,这个while......
  • 协程理论
    (一)基于单线程来实现并发(0)并发的本质基于单线程实现并发即只用一个主线程(可利用的cpu只有一个)的情况下实现并发并发的本质:切换+保存状态cpu正在运行一个任务会在两种情况下去执行其他的任务一:发生了IO阻塞二:该任务的计算事件过长或者有一个优先级更高的任务代......
  • 编辑jar包中class文件的几种方式
    原文地址blog.csdn.net在日常的开发中经常使用到第三方一些库,这些库可能提供gradle仓库的依赖,也可能提供jar包,有时候为了我们的一些自定义操作,需要修改这些jar包中的代码.这个时候该怎么做呢?我所了解的可以修改jar中class的几种方式aop编程,使用aop框架hook想要修改的......