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

2024-05-02 07:20

本文主要是介绍设计模式-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,从而获得其好处,同时避免其潜在的缺点。

这篇关于设计模式-02 设计模式-接口隔离原则案例分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/953698

相关文章

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(