SHOW ME THE CODE - 面向对象程序设计之 - 接口隔离原则(ISP)

2024-05-04 19:36

本文主要是介绍SHOW ME THE CODE - 面向对象程序设计之 - 接口隔离原则(ISP),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SHOW ME THE CODE - 面向对象设计系列

  • 1 SHOW ME THE CODE - 面向对象基本概念
  • 2 SHOW ME THE CODE - 面向对象程序设计之 - 单一职责原则(SRP)
  • 3 SHOW ME THE CODE - 面向对象程序设计之 - 开闭原则(OCP)
  • 4 SHOW ME THE CODE - 面向对象程序设计之 - 里氏替换原则(LSP)
  • 5 SHOW ME THE CODE - 面向对象程序设计之 - 接口隔离原则(ISP)

你的新手机有预装软件吗?

手机已经是生活必须品

再开始今天的主题之前我们先来看一个我们现实生活中大家都曾经遇到过的场景。当今社会手机已经成为了人们日常生活的必备品,除了很小的小朋友可能没有手机,其余的人基本上都拥有属于自已的手机。

新手机开箱,能装多少是多少

很多人都购买过新手机,有些人换机的频率还很高。当我们购买了一部新手机,按下电源键开机,并进行了基本的初始化设置后,首次进入手机的桌面,我想问一问大家的感受是什么?大家是否发现除了手机系统自带的系统必备的一些系统软件之外,很多的应用已经安装到了你的手机里,这些应用我们称之为预装应用。
比如说抖音、淘宝、支付宝、大众点评、头条、携程、QQ、微信、腾讯视频、优酷视频、拼多多、百度地图、哔哩哔哩等等,根据不同的手机厂商,预装的软件会有所不同。而且当我们打开手机应用商店,稍不留神就会下装安装一大堆“推荐安装”的应用。

我不需要的,请不要给我

当我买了一个新手机,第一件事情就是把一些用不上的APP卸载了,比如说:抖音,头条,携程,优酷视频,以及一些系统自带的很多用不上的其它应用。

之所以这么做,就是新手机预装了我不想要,且不需要,且让人反感的应用。为了手机,我被迫安装了不需要的东西,为了解决这个问题,我需要花额外的时间来卸载这些应用。

而今天我们要谈的“接口隔离原则(ISP)”,和手机的例子有相似之处,那就是我不需要的,请不要给我,否则我会很难受。

接口隔离原则

接口隔离原则的定义

接口隔离原则(Interface Segregation Principle,ISP)是面向对象设计中的一个原则,由罗伯特·C·马丁(Robert C. Martin),江湖人称:Uncle Bob, 鲍勃大叔,在他的著作《敏捷软件开发:原则、模式与实践》(Agile Software Development: Principles, Patterns, and Practices)中提出。
该原则的定义是:客户端不应该依赖于它不需要的接口

怎么理解“接口”

我们可以把接口比作剧本中的角色,而该角色在剧中由哪个演员来扮演则想当于接口的由哪个具体的类来实现。所以,一个接口应该简单的代表一个角色,而不是多个角色。

怎么理解接口隔离

接口隔离原则主要是为了防止设计出大而全的单一接口,这种接口通常包含了不同客户端所需的所有方法。

当我们进行设计接口时,应该将其设计得尽可能精简,只包含客户端需要的方法,而不应该强迫客户端去依赖于它们不需要的方法。接口隔离原则强调了接口的单一性和独立性,以减少类之间的耦合度,提高系统的灵活性、可维护性和可扩展性。

SHOW ME THE CODE

A Bad Example: All in One Interface

我们定义了一个用户管理的接口:UserManagement,里面包含用户创建更新操作,用户组操作,找回密码操作,我们的接口实现类:UserManagementService就是一个包含了所有操作的大类。

public interface UserManagement
{//创建用户,更新用户void createUser(User user);void updateUser(User user);//用户组操作List<User> getUserByGroup(String group);void addToGroup(User user, String group);void removeFromGroup(User user, String group);//找回密码String sendVerificationCode(User user, String phoneNumber);void verifyCode(String code);void resetPassword(User user, String newPassword);
}public class UserManagementService implements UserManagement
{//创建用户,更新用户@Overridepublic void createUser(User user){//user creation logic}@Overridepublic void updateUser(User user){//update logic}//用户组操作@Overridepublic List<User> getUserByGroup(String group){//query users by group name, return a list of user by a specific group}@Overridepublic void addToGroup(User user, String group){//add a user to a group}@Overridepublic void removeFromGroup(User user, String group){//remove a user from a group}//找回密码@Overridepublic String sendVerificationCode(User user, String phoneNumber){//update logic}@Overridepublic void verifyCode(String code){//update logic}@Overridepublic void resetPassword(User user, String newPassword){//update logic}
}

如何重构,—>接口拆分

需要对上面的UserManagement接口和其实现类进行如下拆分

拆分后接口
IUserMng
IUserGroup
IPswChange
拆分后实现类
UserService
UserGroupService
PswChangeService
public interface IUserMng
{//创建用户,更新用户void createUser(User user);void updateUser(User user);
}	public interface IUserGroup
{//用户组操作List<User> getUserByGroup(String group);void addToGroup(User user, String group);void removeFromGroup(User user, String group);
}public interface IPswChange
{	//找回密码String sendVerificationCode(User user, String phoneNumber);void verifyCode(String code);void resetPassword(User user, String newPassword);
}public class UserService implements IUserMng
{//创建用户,更新用户@Overridepublic void createUser(User user){//user creation logic}@Overridepublic void updateUser(User user){//update logic}
}public class UserGroupService implements IUserGroup
{	//用户组操作@Overridepublic List<User> getUserByGroup(String group){//query users by group name, return a list of user by a specific group}@Overridepublic void addToGroup(User user, String group){//add a user to a group}@Overridepublic void removeFromGroup(User user, String group){//remove a user from a group}
}public class PswChangeService implements IPswChange
{	//找回密码@Overridepublic String sendVerificationCode(User user, String phoneNumber){//update logic}@Overridepublic void verifyCode(String code){//update logic}@Overridepublic void resetPassword(User user, String newPassword){//update logic}
}

接口隔离原则与其他设计原则的关系

在面向对象的几大设计原则中,每一个原则又与其它的原则有着密切的关系,他们共同的目标都是围绕软件的可扩展,可维护,灵活性以及降低代码的耦合度。

接口隔离原则与其他一些设计原则密切相关,例如:

**单一职责原则(SRP):**接口应该只包含那些与其功能密切相关的的方法,这与单一职责原则相符。
**依赖倒置原则(DIP):**接口应该被抽象类或接口所依赖,而不是具体类,这与依赖倒置原则相符。
**开闭原则(OCP):**接口应该对扩展开放,对修改封闭,这与开闭原则相符。

接口隔离与单一职责的比较

  • 适用范围不同:
    • 单一职责原则(SRP)主要关注的是类或模块的设计,它要求一个类或模块应该只有一个引起它变化的原因,即一个类或模块应该只有一个责任。
    • 接口隔离原则(ISP)更多地关注接口的设计,它要求接口的设计应该精简单一,客户端不应该依赖于它们不需要的接口。
  • 关注点不同:
    • SRP关注的是类或模块内部的责任分配,即一个类或模块应该负责完成一个特定的任务。
    • 而ISP关注的是类或模块与外部的交互,即接口的设计应该满足客户端的需求,不应该强迫客户端依赖于它们不需要的方法。
  • 侧重点不同:
    • SRP侧重于避免一个类或模块内部功能的混乱和耦合,通过将不同的职责分离到不同的类或模块中来提高内聚性和降低耦合性。
    • 而ISP侧重于避免类或模块与外部的依赖关系过于紧密,通过精简接口的设计来减少客户端与接口的耦合度。

希望这篇文章可以帮助大家理解什么是接口隔离原则,欢迎大家一起交流。

关注我的公众号

欢迎大家关注、点赞、转发,一起交流软件开发、架构设计、云原生技术。
TXZQ聊IT技术与架构

这篇关于SHOW ME THE CODE - 面向对象程序设计之 - 接口隔离原则(ISP)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

JVM内存调优原则及几种JVM内存调优方法

JVM内存调优原则及几种JVM内存调优方法 1、堆大小设置。 2、回收器选择。   1、在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。   2、对JVM内存的系统级的调优主要的目的是减少

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

ffmpeg面向对象-待定

1.常用对象 rtsp拉流第一步都是avformat_open_input,其入参可以看下怎么用: AVFormatContext *fmt_ctx = NULL;result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); 其中fmt_ctx 如何分配内存的?如下 int avformat_open_input(

Debugging Lua Project created in Cocos Code IDE creates “Waiting for debugger to connect” in Win-7

转自 I Installed Cocos Code IDE and created a new Lua Project. When Debugging the Project(F11) the game window pops up and gives me the message waiting for debugger to connect and then freezes. Also a

07 v-if和v-show使用和区别

划重点: v-ifv-show 小葱拌豆腐 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="

LLVM入门2:如何基于自己的代码生成IR-LLVM IR code generation实例介绍

概述 本节将通过一个简单的例子来介绍如何生成llvm IR,以Kaleidoscope IR中的例子为例,我们基于LLVM接口构建一个简单的编译器,实现简单的语句解析并转化为LLVM IR,生成对应的LLVM IR部分,代码如下,文件名为toy.cpp,先给出代码,后面会详细介绍每一步分代码: #include "llvm/ADT/APFloat.h"#include "llvm/ADT/S

chapter06 面向对象基础 知识点Note

文章目录 前言类的设计 属性和行为对象的内存解析 (堆 栈 方法区)类的成员之一 变量(属性) field类的成员之二 方法 method对象数组方法重载 overload可变个数的形参 语法糖方法的值传递机制递归关键字package importMVC设计模式import导入面向对象特征之一 封装类的成员之三 构造器JavaBeanUML类图 前言 ` 面向对象封装 面向

VS Code 调试go程序的相关配置说明

用 VS code 调试Go程序需要在.vscode/launch.json文件中增加如下配置:  // launch.json{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information,

智能工厂程序设计 之1 智能工厂都本俱的方面(Facet,Aspect和Respect)即智能依赖的基底Substrate 之1

Q1、昨天分别给出了三个智能工厂的 “面face”(里面inter-face,外面outer-face和表面surface) 以及每个“面face” 各自使用的“方”(StringProcessor,CaseFilter和ModeAdapter)  。今天我们将继续说说三个智能工厂的“方面” 。在展开之前先看一下三个单词:面向facing,取向oriented,朝向toword。理解这三个词 和