设计模式-02 设计模式-接口隔离原则案例分析

1.定义

接口隔离原则(Interface Segregation Principle,简称 ISP)是设计模式中的一个原则,它规定客户端不应该依赖它不使用的方法。

换句话说,接口应该被细分为更小的、更具体的接口,以便客户端只依赖于它们需要的方法。

(客户端)|V(公共行为)            (特定行为)         (特定行为)+------------+         +-------------+        +-------------+|  I公共接口  |         | I特定接口1 |        | I特定接口2 |+------------+         +-------------+        +-------------+|               |              |V               V              V+-------+     +---------+     +---------+| 客户端1 |     | 客户端2 |     | 客户端3 |+-------+     +---------+     +---------+

2.内涵


接口应该被细分的足够少,接口与接口直接不应该有依赖,ISP 的目的是提高代码的灵活性、可维护性和可测试性。总结起来,ISP原则的好处和缺点如下。
ISP 的好处

  •     提高代码的灵活性
  •     提高代码的可维护性
  •     提高代码的可测试性
  •     减少耦合
  •     提高代码的可重用性

ISP 的缺点

  •     可能导致更多的接口
  •     可能增加代码的复杂性
3.案例对比

例如,以机器类的定义为例,假如一个机器可以打印机,复印机,发传真机,如果不加以深入思考,我们可能如下第一种方式定义。


bad 设计

//
// Created by Administrator on 2024/5/1.
//
#include <iostream>
using namespace std;
struct Document;
struct IMachine{virtual void print(Document& doc) = 0;virtual void scan(Document& doc) = 0;virtual void fax(Document& doc) = 0;};
// 接口分离原则// 发现 MFP  只需要 print 功能即可
// 其他接口到底怎么处理比较好?
struct MFP:IMachine{void print(Document &doc) override {// ok}void scan(Document &doc) override {}void fax(Document &doc) override {}
};// 发现scanner 只需要 scan 功能
// 其他接口到底怎么处理比较好?
struct Scanner:IMachine{void print(Document &doc) override {// do what?}void scan(Document &doc) override {// ok}void fax(Document &doc) override {// do what?}
};

如果后面的传真机怎么定义?,除了fax 函数外,其他函数的功能并不是fax 需要的。

好的设计

#include <iostream>
using namespace std;
struct Document;// 接口分离
struct IPrinter{virtual void print(Document& doc) =0 ;
};struct IScanner {virtual void scan(Document& doc)=0 ;
};struct IFax{virtual void fax(Document& doc)=0 ;
};struct IMachine:IPrinter,IScanner {};struct Machine:IMachine{IPrinter& printer;IScanner& scanner;Machine(IPrinter &printer, IScanner &scanner):printer(printer),scanner(scanner){}void print(Document &doc) override {printer.print(doc);}void scan(Document &doc) override {scanner.scan(doc);}
};

这种设计,我们可以任意进行组合,组合出不同特性的子类,自由度更高。

4.注意事项


在实际开发中应用接口隔离原则(ISP)时,需要注意以下几点:

  • 识别公共行为。第一步是识别客户端共享的公共行为。这些行为可以被抽象到一个公共接口中。
  • 细化接口。对于任何不属于公共行为的方法,都应该将其细化到一个单独的接口中。
  • 考虑可扩展性。在设计接口时,考虑未来的可扩展性。避免将不相关的功能包含在同一个接口中。
  • 使用依赖注入。依赖注入是一种技术,它允许客户端只依赖于它们需要的接口。这有助于实现松耦合和可测试性。
  • 避免使用继承。继承是一种实现代码重用的强大机制,但它也可能导致违反 ISP。如果可能的话,优先使用组合而不是继承。

5.最佳实践


注意的具体示例:

  • 避免创建上帝接口。上帝接口是一个包含大量方法的大型接口。客户端通常只使用其中一小部分方法,但仍然必须实现所有方法。这违反了 ISP,并可能导致不必要的代码和维护开销。
  • 避免使用可选方法。可选方法允许客户端选择性地实现接口中的某些方法。这可能导致代码混乱和不可预测的行为。如果可能的话,避免使用可选方法,而是创建单独的接口来表示可选的行为。
  • 考虑未来需求。在设计接口时,考虑未来的需求。避免将不相关的功能包含在同一个接口中,因为这可能会限制接口的未来可扩展性。

6.总结


应用 ISP 时,权衡其优点和缺点非常重要。ISP 可以提高代码的灵活性、可维护性和可测试性,但它也可能导致更多的接口和增加代码的复杂性。

总体而言,ISP 是一个有用的设计原则,它可以帮助提高代码的质量。通过遵循上述准则,开发人员可以有效地应用 ISP,从而获得其好处,同时避免其潜在的缺点。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive 与 MySQL 的数据库限制对比

数据库的大小 Hive: 由于Hive是建立在Hadoop生态系统之上&#xff0c;理论上其数据库大小仅受Hadoop分布式文件系统&#xff08;HDFS&#xff09;的限制&#xff0c;可以达到PB级别或更高。MySQL: MySQL数据库的大小受到磁盘空间和文件系统的限制。在实践中&#xff0c;单个实例…

Web后端开发中对三层架构解耦之控制反转与依赖注入

内聚与耦合 内聚 比如说我们刚刚书写的员工的实现类 在这里我们仅仅书写的是和员工相关的代码 而与员工无关的代码都没有放到这里 说明内聚程度较高 耦合 以后软件开发要高内聚 低耦合 提高程序灵活性 扩拓展性 分析代码 如何解耦 创建容器 提供一个容器 存储东西 存储E…

STM32 F103C8T6学习笔记16:1.3寸OLED的驱动显示日历

今天尝试使用STM32 F103C8T6驱动显示 1.3寸的OLED&#xff0c;显示数字、字符串、汉字、图片等 本质与0.96寸的OLED是完全相同的原理&#xff1a; 而且经过我的研究发现: 1.3寸大小的OLED并未比0.96寸的有更多的显示像素点数来显示&#xff0c;也是128*64的像素点数显示: 也…

AI期末复习(PolyU)

文档详见评论链接 Tutorial 2-Search Algorithm Breadth-first search宽度优先搜索 [图片] [图片] open表由queue队列实现&#xff0c;因此加在尾部。 [图片] Depth-first search深度优先搜索 [图片] [图片] open表由stack栈实现&#xff0c;因此加在头部。 [图片] Hill climbi…

【设计模式】之单例模式

系列文章目录 【设计模式】之责任链模式【设计模式】之策略模式【设计模式】之模板方法模式 文章目录 系列文章目录 前言 一、什么是单例模式 二、如何使用单例模式 1.单线程使用 2.多线程使用&#xff08;一&#xff09; 3.多线程使用&#xff08;二&#xff09; 4.多线程使用…

uni框架下的前端小知识

<movable-area> 和 <movable-view> 组件来创建一个可以移动的区域&#xff0c;这通常用于模拟地图或座位图等场景的拖动效果。 1、direction&#xff1a;移动方向&#xff0c;可选值为all、vertical、horizontal分别表示所有方向、垂直、水平方向。 2、inertia&am…

力扣153. 寻找旋转排序数组中的最小值

Problem: 153. 寻找旋转排序数组中的最小值 文章目录 题目描述思路复杂度Code 题目描述 思路 1.初始化左右指针left和right&#xff0c;指向数组的头和尾&#xff1b; 2.开始二分查找&#xff1a; 2.1.定义退出条件&#xff1a;当left right时退出循环&#xff1b; 2.2.当nums…

Python爬虫-BeautifulSoup解析

1.简介 BeautifulSoup 是一个用于解析 HTML 和 XML 文档的 Python 库。它提供了一种灵活且方便的方式来导航、搜索和修改树结构或标记文档。这个库非常适合网页抓取和数据提取任务&#xff0c;因为它允许你以非常直观的方式查询和操作文档内容。 2.安装 Beautiful Soup 终端输…

docker学习笔记5:Docker Compose安装与使用

Docker Compose 简介 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用一个 YAML 文件来配置应用服务,这样可以通过一个简单的命令创建和启动所有服务。Docker Compose 主要面向开发环境、自动化测试环境和小型生产部署。 Docker Compose 的主要特…

Time_embedding采样的理解

简单概括&#xff0c;就是t越大&#xff0c;采样得到的点越分散&#xff0c;采样得到的点范围更广 一个简单的示例函数 def time_embedding(t, max_steps1000):frequency np.linspace(0, 1, max_steps)embeddings np.concatenate([np.sin(frequency * t * math.pi),np.cos(f…

【笔记】 - Git

一、安装 https://git-scm.com/ 下载 下一步下一步 二、clone 到本地 1、git clone [url] Git 会按照你提供的 URL 所指向的项目的名称创建你的本地项目目录。 通常就是该 URL 最后一个 / 之后的项目名称。如果你想要一个不一样的名字&#xff0c; 你可以在该命令后加上你想要…

【webrtc】RemoteAudioSource的创建线程

m98 代码&#xff1a;I:\webrtc m98_yjf\src\pc\rtp_transmission_manager.cc RtpTransmissionManager::CreateReceiver 在信令线程创建receiver receiver 是&#xff1a; rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>receiver;其实际…

可视化大屏在真实场景的效果,绝对震撼,不要再嘲笑其作用了

hello&#xff0c;我是大千UI工场&#xff0c;本地带来一批可视化大屏现场效果图&#xff0c;非常震撼&#xff0c;给大家带来身临其境的感受&#xff0c;欢迎关注点赞&#xff0c;有需求请私信。 有人可能会认为可视化大屏没有太多价值&#xff0c;可能是因为以下几个原因&am…

记录PR学习查漏补缺

记录PR学习查漏补缺 常用快捷键文件编辑素材序列标记字幕窗口帮助 效果基本3D高斯模糊查找边缘色彩颜色平衡超级键马赛克中间值变形稳定器 常用 快捷键 注意&#xff1a;比较常用的用红色字体显示 文件 快捷键作用Ctrl Alt N新建项目Ctrl O打开项目Ctrl I导入Ctrl S保存…

链表面试题1.

1&#xff0c;反转一个单链表 采用头插法即可 class Solution {public ListNode reverseList(ListNode head) {if(head null){return head;}ListNode cur head.next;head.next null;while(cur ! null){ListNode curN cur.next;cur.next head;head cur ;cur curN;}return …

WEB攻防-PHP特性-piwigoCMS审计实例

前置知识&#xff1a;PHP函数缺陷 测试环境 &#xff1a;piwigo CMS 漏洞URL&#xff1a; 漏洞文件位置&#xff1a;\include \functions_rate.inc.php 漏洞产生入口文件&#xff1a;/picture.php picture.php中接受了一个GET方法action参数&#xff0c;作为switch...case.…

【Java探索之旅】包管理精粹 Java中包的概念与实践

文章目录 &#x1f4d1;前言一、封装1.1 封装的概念1.2 访问限定修饰符 二、封装扩展&#xff08;包&#xff09;2.1 包的概念2.2 带入包中的类2.3 自定义包2.4 常见的包 &#x1f324;️全篇总结 &#x1f4d1;前言 在Java编程中&#xff0c;封装是面向对象编程的核心概念之一…

知识产权 | 守护科技创新之光,共筑知识产权长城

2024年4月26日&#xff0c;迎来了一年一度的世界知识产权日&#xff0c;今年的主题是&#xff1a;“立足创新创造&#xff0c;构建共同未来。” 易我科技是一家专注于数据安全产品研发、生产、销售、服务一体化的高新技术软件企业。易我科技自成立以来&#xff0c;始终秉持尊重…

树莓派4B安装安卓系统LineageOS 21(Android14)

1&#xff1a;系统下载 2&#xff1a;下载好镜像后&#xff0c;准备写入SD卡&#xff0c;我这边使用的是 balenaetcher 3&#xff1a;插入树莓派&#xff0c;按照指示一步一步进行配置&#xff0c;可以配置时区&#xff0c;语言。 注意点 1》:想返回的时候按F2 2》:进入系统…

Redisson分布式锁,重试锁和锁续命的原理

RedissonLock 锁重试原理 tryLock有三个三个参数&#xff0c;第一个是等待时间&#xff0c;第二个是锁失效后自动释放的时间,不填默认为-1&#xff0c;第三个是时间单位&#xff1b; 当设置了第一个参数&#xff0c;那这个锁就成了可重试锁&#xff1b;获取锁失败后&#xff0c…