当前位置: 首页 > news >正文

设计模式—接口隔离原则(ISP)

1.背景

2002 年罗伯特·C.马丁给“接口隔离原则”的定义是:客户端不应该被迫依赖于它不使用的方法(Clients should not be forced to depend on methods they do not use)。该原则还有另外一个定义:一个类对另一个类的依赖应该建立在最小的接口上(The dependency of one class to another one should depend on the smallest possible interface)。

2.概念

接口隔离原则(Interface Segregation Principle,ISP)要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。

通俗的讲:

  • 一个类对另外一个类的依赖性应当是建立在最小的接口上的;

  • 一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染;

  • 使用多个专门的接口比使用单一的总接口要好;

  • 不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变;

接口隔离原则和单一职责原则很像,都是为了提高类的内聚性、降低它们之间的耦合性,体现了封装的思想,但两者是不同的:

  • 单一职责原则注重的是职责,而接口隔离原则注重的是对接口依赖的隔离。

  • 单一职责原则主要是约束类,它针对的是程序中的实现和细节;接口隔离原则主要约束接口,主要针对抽象和程序整体框架的构建。

应用接口隔离原则的建议:

  • 接口尽量小,但是要有限度,既不能是大而全的接口也不能是一个方法一个接口,这样就失去了面向抽象的意义,应该按照功能的密不可分来定义接口,而且应该是动态的,因为随着业务发展功能需求是有变化的,所以我们在设计的时候要考虑留好提前量,避免抽象的变化;

  • 为依赖接口的类定制服务,只提供调用者需要的方法,屏蔽不需要的方法;

  • 了解环境,拒绝盲从,每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑;

  • 提高内聚,减少对外交互,使接口用最少的方法去完成最多的事情;

3.案例分析

需求:我们要开发一个学生成绩管理项目,包含插入成绩、删除成绩、修改成绩、计算总分、计算均分、打印成绩信息、査询成绩信息等功能;如果将这些功能全部放到一个接口中显然不太合理,正确的做法是将它们分别放在输入模块、统计模块和打印模块等 3 个模块中。

/// <summary>/// 输入模块/// </summary>public interface IInputModule{/// <summary>/// 添加成绩/// </summary>void Insert();/// <summary>/// 删除成绩/// </summary>void Delete();/// <summary>/// 修改成绩/// </summary>void Modify();}/// <summary>/// 统计模块/// </summary>public interface ICountModule{/// <summary>/// 计算总分/// </summary>void CountTotalScore();/// <summary>/// 计算平均分/// </summary>void CountAverage();}/// <summary>/// 打印模块/// </summary>public interface IPrintModule{/// <summary>/// 打印学生信息/// </summary>void PrintStudentInfo();/// <summary>/// 查询学生信息/// </summary>void QueryStudentInfo();}/// <summary>/// 实现类/// </summary>public class StudentSoreList : IInputModule, ICountModule, IPrintModule{private StudentSoreList(){}public static IInputModule GetInputModule(){return (IInputModule)new StudentSoreList();}public static ICountModule GetCountModule(){return (ICountModule)new StudentSoreList();}public static IPrintModule GetPrintModule(){return (IPrintModule)new StudentSoreList();}public void Insert(){Console.WriteLine("输入模块的Insert()方法被调用!");}public void Delete(){Console.WriteLine("输入模块的Delete()方法被调用!");}public void Modify(){Console.WriteLine("输入模块的Modify()方法被调用!");}public void CountTotalScore(){Console.WriteLine("统计模块的CountTotalScore()方法被调用!");}public void CountAverage(){Console.WriteLine("统计模块的CountAverage()方法被调用!");}public void PrintStudentInfo(){Console.WriteLine("打印模块的PrintStudentInfo()方法被调用!");}public void QueryStudentInfo(){Console.WriteLine("打印模块的QueryStudentInfo()方法被调用!");}}{//ISP:接口隔离原则IInputModule inputModule = StudentSoreList.GetInputModule();inputModule.Insert();ICountModule countModule = StudentSoreList.GetCountModule();countModule.CountTotalScore();IPrintModule printModule = StudentSoreList.GetPrintModule();printModule.PrintStudentInfo();}

4.优缺点

优点:

  • 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性;

  • 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性;

  • 如果接口的粒度大小定义合理,能够保证系统的稳定性;但是,如果定义过小,则会造成接口数量过多,使设计复杂化;如果定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险;

  • 使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义;

  • 能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码;

缺点:

  • 需要掌握接口细分的程度,如果太细,会造成接口膨胀,增加系统的复杂性;

相关文章:

设计模式—接口隔离原则(ISP)

1.背景 2002 年罗伯特C.马丁给“接口隔离原则”的定义是&#xff1a;客户端不应该被迫依赖于它不使用的方法&#xff08;Clients should not be forced to depend on methods they do not use&#xff09;。该原则还有另外一个定义&#xff1a;一个类对另一个类的依赖应该建立…...

Jenkins用126邮箱发邮件为什么发不出去

1、检查 Jenkins Location中的邮件地址配置与发邮件的地址配置是否一致 Manage Jenkins -》 system 2、检查地址和端口号 3、检查邮箱的登录配置是否正确&#xff08;这个地方的配置方式网上一抓一大把&#xff0c;自己搜一下就好&#xff09; 4、126邮箱发邮件不需要勾选ssl协…...

怎么给数据库某个字段建立一个前缀索引

说明&#xff1a;SQL调优中重要的一个环节是建立索引&#xff0c;其中有一条是字段值过长字段应该建立前缀索引&#xff0c;即根据字段值的前几位建立索引&#xff0c;像数据库中的密码字段、UUID字段。 因为其随机性&#xff0c;其实根据前几位就可以锁定某一条记录了。前缀索…...

C# 图片下载工具类

写在前面 从浏览器的Html文本中获取图片链接并保存到本地&#xff0c;同时对图片的分辨率和品质进行处理&#xff0c;以满足某些平台的规格需求&#xff1b;可以放到多线程中调用以提高下载效率。 代码实现 public class ImageDownloader{private int minImageSize 1024 * 1…...

嵌入式硬件电路·电平

目录 1. 电平的概念 1.1 高电平 1.2 低电平 2. 电平的使用场景 2.1 高电平使能 2.2 低电平使能 2.3 失能 1. 电平的概念 电平是指电信号电压的大小或高低状态。在数字电子学中&#xff0c;电平有两种状态&#xff0c;高电平和低电平&#xff0c;用来表示二进制中…...

Python文件路径常用操作

1 文件路径 在进行数据处理时&#xff0c;经常要用代码去读文件里的数据&#xff0c;那么首先就得知道这个文件的文件路径。文件路径简单地说就是文件的存放位置。文件路径分为两块&#xff1a;文件夹路径和文件名&#xff0c;文件名又分为文件基本名和扩展名。 举例说明&…...

Redis-Redis 高并发分布式锁

集群分布式场景高并发 1.negix配置代理和路由 高并发场景超卖问题 1.使用原生redis控制超卖时(若是商品&#xff0c;则可以将商品id作为锁对象)&#xff0c;会遇到的问题 问题一&#xff1a;若直接使用&#xff1a;将获取锁的对象和设置的超时的时间分开&#xff0c;则不能控…...

【推荐系统】MMOE笔记 20231126

paper阅读 任务差异带来的固有冲突实际上会损害至少某些任务的预测&#xff0c;特别是当模型参数在所有任务之间广泛共享时。&#xff08;在说ESMM&#xff09; 共享底层参数可以减少过拟合风险&#xff0c;但是会遇到任务差异引起的优化冲突&#xff0c;因为所有任务都需要在…...

4. 标准 IO 库

4. 标准 IO 库 1. 标准 IO 简介2. FILE 指针3. 标准输入、标准输出和标准错误4. fopen() 和 flose()5. fread() 和 fwrite()6. fseek 定位7. 检查或复位状态7.1 feof()7.2 ferrof()7.3 clearerr() 8. 格式化 IO8.1 格式化输出8. 2 格式化输入 9. IO 缓冲9.1 文件 IO 的内核缓冲…...

SAP Smartform小结

SAP系统做打印单据用的, 感觉很不好用, 特别是要嵌入韩文时必须使用嵌入的word编辑器,运行速度简直不可忍受. 见过一些Adobe interactive form的示例, 看着相当不错, 不过据说需要花money额外买licence, 哪有smartform这种免费东西来得实惠. 一般打印需求,会要求有标题抬头,打…...

KVM虚拟机的NAT网络模式原理及过程展示

NAT的方式及原理 NAT方式是KVM安装后的默认方式。 它支持主机与虚拟机的互访&#xff0c;同时也支持虚拟机访问互联网&#xff0c;但不支持外界访问虚拟机。 default是宿主机安装虚拟机支持模块的时候自动安装的。 其中 virbr0是由宿主机虚拟机支持模块安装时产生的虚拟网络接…...

亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(一) ​

随着大语言模型效果明显提升&#xff0c;其相关的应用不断涌现呈现出越来越火爆的趋势。其中一种比较被广泛关注的技术路线是大语言模型&#xff08;LLM&#xff09;知识召回&#xff08;Knowledge Retrieval&#xff09;的方式&#xff0c;在私域知识问答方面可以很好的弥补通…...

C# MemoryCache的使用和封装

封装个缓存类&#xff0c;方便下次使用。 using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic;namespace Order.Core.API.Cache {public class GlobalCache C#有偿Q群&#xff1a;927860652{private static readonly MemoryCache …...

【nlp】4.2 nlp中标准数据集(GLUE数据集合中的dev.tsv 、test.tsv 、train.tsv)

nlp中标准数据集 1 GLUE数据集合介绍1.1 数据集合介绍1.2 数据集合路径2 GLUE子数据集的样式及其任务类型2.1 CoLA数据集文件样式2.2 SST-2数据集文件样式2.3 MRPC数据集文件样式2.4 STS-B数据集文件样式2.5 QQP数据集文件样式2.6 (MNLI/SNLI)数据集文件样式2.7 (QNLI/RTE/WNLI…...

Java LinkedList

LinkedList 一个双向链表。 本身是基于链表进行封装的列表, 所以具备了链表的特性: 变更简单, 容量是无限的, 不必像数组提前声明容量等。 同时 LinkedList 支持存储包括 null 在内的所有数据类型。 1 链表 了解 LinkedList 之前, 我们需要先了解一下双向链的特点 单链表, 双…...

【单片机学习笔记】STC8H1K08参考手册学习笔记

STC8H1K08参考手册学习笔记 STC8H系列芯片STC8H1K08开发环境串口烧录 STC8H系列芯片 STC8H 系列单片机是不需要外部晶振和外部复位的单片机&#xff0c;是以超强抗干扰/超低价/高速/低功耗为目标的 8051 单片机,在相同的工作频率下,STC8H 系列单片机比传统的 8051约快12 倍速度…...

RevCol:可逆的柱状神经网络

文章目录 摘要1、简介2、方法2.1、Multi-LeVEl ReVERsible Unit2.2、可逆列架构2.2.1、MACRo设计2.2.2、MicRo 设计2.3、中间监督3、实验部分3.1、图像分类3.2、目标检测3.3、语义分割3.4、与SOTA基础模型的系统级比较3.5、更多分析实验3.5.1、可逆列架构的性能提升3.5.2、可逆…...

HCIA-RS基础-RIP路由协议

前言&#xff1a; RIP路由协议是一种常用的距离矢量路由协议&#xff0c;广泛应用于小规模网络中。本文将详细介绍RIP路由协议的两个版本&#xff1a;RIPv1和RIPv2&#xff0c;并介绍RIP的常用配置命令。通过学习本文&#xff0c;您将能够掌握RIP协议的基本原理、RIPv1和RIPv2的…...

虚拟化逻辑架构: LBR 网桥基础管理

目录 一、理论 1.Linux Bridge 二、实验 1.LBR 网桥管理 三、问题 1.Linux虚拟交换机如何增删 一、理论 1.Linux Bridge Linux Bridge&#xff08;网桥&#xff09;是用纯软件实现的虚拟交换机&#xff0c;有着和物理交换机相同的功能&#xff0c;例如二层交换&#…...

【Spring之AOP底层源码解析,持续更新中~~~】

文章目录 一、动态代理1.1、ProxyFactory1.2、Advice的分类1.3、Advisor的理解 二、创建代理对象的方式2.1、ProxyFactoryBean2.2、BeanNameAutoProxyCreator2.3、DefaultAdvisorAutoProxyCreator 三、Spring AOP的理解3.1、AOP中的概念3.2、Advice在Spring AOP中对应API3.3、T…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...