「撸一手好代码」设计模式之开闭原则

ops/2024/10/22 4:16:19/

「撸一手好代码」设计模式开闭原则

什么是开闭原则

开闭原则(Open-Closed Principle, OCP)是指软件实体(如类、模块、函数等)应当对扩展开放,对修改关闭。这意味着软件系统的设计应当允许在不修改现有代码的基础上,通过添加新的代码来扩展新的功能或行为。

为什么需要开闭原则

  1. 提高可维护性:减少因需求变更而必须修改现有代码的情况,降低出错的风险。
  2. 增强可扩展性:支持在不破坏现有系统的情况下,轻松添加新功能。
  3. 促进复用:设计良好的、遵循开闭原则的组件更容易被其他系统或模块复用。

如何应用开闭原则

  1. 识别变化点:首先,识别出系统中可能发生变化的部分。
  2. 抽象化:针对变化点,设计抽象类或接口,将稳定部分和变化部分分离。
  3. 依赖抽象:在代码中尽量使用抽象类或接口来引用对象,而不是具体的实现类。
  4. 多态实现:通过多态机制,在运行时动态地选择具体的实现类,从而实现扩展而不修改原有代码。

反向示例及后果

反向示例

假设我们有一个简单的支付系统,初期只支持信用卡支付。随着业务的发展,需要添加支付宝和微信支付的支持。但系统设计时没有遵循开闭原则,直接将支付逻辑硬编码在PaymentService类中。

public class PaymentService {public void pay(String paymentType, double amount) {if ("credit_card".equals(paymentType)) {// 信用卡支付逻辑System.out.println("Processing credit card payment for " + amount);} else {throw new UnsupportedOperationException("Unsupported payment type: " + paymentType);}}
}

后果

● 当需要添加新的支付方式时,必须修改PaymentService类,增加新的条件分支,违反了开闭原则
● 随着支付方式的增多,pay方法将变得复杂且难以维护。
解决方案
我们可以通过引入支付接口和具体的支付实现类来重构上述系统,使其遵循开闭原则

// 支付接口
public interface Payment {void pay(double amount);
}
// 信用卡支付实现
public class CreditCardPayment implements Payment {@Overridepublic void pay(double amount) {System.out.println("Processing credit card payment for " + amount);}
}
// 支付宝支付实现
public class AlipayPayment implements Payment {@Overridepublic void pay(double amount) {System.out.println("Processing alipay payment for " + amount);}
}
// 支付服务类,依赖抽象
public class PaymentService {private Payment payment;public PaymentService(Payment payment) {this.payment = payment;}public void processPayment(double amount) {payment.pay(amount);}
}

现在,当需要添加新的支付方式时,只需实现Payment接口并创建相应的实例,然后将其传递给PaymentService类即可,无需修改现有代码。


http://www.ppmy.cn/ops/127093.html

相关文章

Vue 文件类型声明

.vue后缀类型声明 我们在 main.ts 文件中引入其他vue文件的时候,是没有类型声明的,也就是说我们知道引入了一个vue文件,但是我们不知道这个文件是准备干嘛的。所以我们需要单独为这个加上一个类型的声明。如果说没有声明也没有报错的话&…

零基础Java第八期:一维数组(1)

目录 一、 一维数组的基本概念 1.1. 什么是数组 1.2. 数组的创建及初始化 1.3. 数组的使用 二、数组是引用类型 2.1. 初始JVM的内存分布 2.2. 基本类型变量与引用类型变量 2.3. 引用变量的理解 2.4. null 三、数组的应用场景 3.1. 作为函数的参数 3.2. 作为函数的返…

C#中的信号

在C#中,信号是用于线程间同步的工具,允许线程通过信号进行等待和通知,以控制并发执行。以下是几种常见的信号工具及其用法: 1. ManualResetEvent 和 AutoResetEvent 这两个类都是基于信号量的同步原语。它们都允许线程等待某个信号并决定何时继续执行,区别在于事件被触发…

rabbitmq 工作队列模式

工作队列模式 一、原理流程图 二、基本知识 工作队列模式(Work Queue Model)是一种消息队列模型,生产者将任务分发到队列中,多个消费者从队列中按顺序获取并处理任务。该模式主要用于负载均衡,确保任务能够均匀分配给…

ParallelsDesktop20最新版本虚拟机 一键切换系统 游戏娱乐两不误

让工作生活更高效:Parallels Desktop 20最新版本虚拟机的神奇之处 大家好!👋 今天我要跟大家安利一款让我工作效率飞升的神器——Parallels Desktop 20最新版本虚拟机。作为一个日常需要在不同操作系统间来回穿梭的人,这款软件简直…

白嫖正版xshell和XFTP

在哪里可以下载正版免费的xshell和XFTP,并且还能够获得官网免费持久更新 白嫖步骤 首先直接在浏览器搜索xshell官网 点进官网之后直接点击下载 接着点击免费授权页面 进入之后就可以免费下载了 下载安装完成后填写用户名和邮箱并提交,这里就以xshell为…

os.popen模块

一、前言 有时候在写一些脚本的时候,需要执行一些系统命令(windows/linux),因为这边会比较方便。用python原生的办法就比较复杂。下边就介绍集中常见的方法 二、os.system os.system是python 内置模块,执行命令非常简单。可以将要执行的命令传递进去。…

京存助力北京某电力研究所数据采集

北京某电力研究所已建成了一套以光纤为主,卫星、载波、微波等多种通信方式共存,分层级的电力专用的网络通信架构体系。随着用电、配电对网络的要求提高,以及终端通信入网的迅速发展,迫切地需要高效的通信管理系统来应对大规模、复…