设计模式原则 - 接口隔离原则(二)

news2024/11/22 21:48:41

接口隔离原则

  • 一 官方定义
  • 二 案例演示
    • 普通方案
      • 案例分析
    • 解决方案
      • 解决方案
    • 案例总结
  • 三 与单一职责原则对比

一 官方定义

接口隔离原则(Interface Segregation Principle),又称为ISP原则,官方定义为:

  1. Clients should not be forced to depend upon interfaces that they don’t use.
    (客户端不应该依赖它不需要的接口)
  2. The dependency of one class to another one should depend on the smallest possible
    interface. (类间的依赖关系应该建立在最小的接口上)

基本介绍
通俗的来讲,不要在一个接口里面定义过多的方法,接口应该尽量细化

二 案例演示

假设有这样一个案例场景,现在有一个接口knife,给定他有三个能力,可以切苹果,切番茄,切土豆, 两个类张厨师,李厨师分别具有这些能力,有一个水果店类,假设是需要张师傅来切苹果和切番茄,而另一个蔬菜店类需要李师傅来切番茄和切土豆

普通方案

public class SegregationDemo {
    public static void main(String[] args) {

        //水果店类
        new FruitShop().cutApple(new CookZhang());
        new FruitShop().cutTomato(new CookZhang());

        //蔬菜店类
        new VegetableShop().cutTomato(new CookLi());
        new VegetableShop().cutPotato(new CookLi());
    }
}
// 定义接口knife
interface Knife {
    //切苹果的能力
    void cutApple();

    //切番茄的能力
    void cutTomato();

    //切土豆的能力
    void cutPotato();
}

//张厨师类
class CookZhang implements Knife {
    @Override
    public void cutApple() {
        System.out.println("张厨师正在切苹果");
    }
    @Override
    public void cutTomato() {
        System.out.println("张厨师正在切番茄");
    }

    @Override
    public void cutPotato() {
        System.out.println("张厨师正在切土豆");
    }
}
//李厨师类
class CookLi implements Knife {
    @Override
    public void cutApple() {
        System.out.println("李厨师正在切苹果");
    }

    @Override
    public void cutTomato() {
        System.out.println("李厨师正在切番茄");
    }

    @Override
    public void cutPotato() {
        System.out.println("李厨师正在切土豆");
    }
}

/*假设有这样一个案例场景,现在有一个接口knife,给定他有三个能力,可以切苹果,切番茄,切土豆,两个类张
厨师,李厨师分别具有这些能力,有一个水果店类,假设是需要张师傅来切苹果和切番茄,而另一个蔬菜店类需要
李师傅来切番茄和切土豆*/

//水果店类
class FruitShop {
    // 将接口类型作为参数传入
    public void cutApple(Knife knife) {
        knife.cutApple();
    }

    public void cutTomato(Knife knife) {
        knife.cutTomato();
    }
}

//蔬菜店类
class VegetableShop {

    public void cutTomato(Knife knife) {
        knife.cutTomato();
    }

    public void cutPotato(Knife knife) {
        knife.cutPotato();
    }
}

在这里插入图片描述

案例分析

在这里插入图片描述
1、VegetableShop使用到Knife中两个方法,同样FruitShop也是如此
2、CookZhang,CookLi分别实现Knife这个接口Knifes对于CookZhang,CookLi不是最小的接口,
换句话说CookZhang,CookLi就必须实现他们不需要的方法。导致这个类出现了耦合
这就违反了接口隔离原则(类间的依赖关系应该建立在最小的接口上)

解决方案

解决方案

根据接口隔离原则,我们将Knife拆分为三个独立的接口不就行了吗!
步骤:

  1. 将Knife拆分为AppleKnife,TomatoKinfe,PotatoKnife三个独立的接口
  2. CookZhang(张厨师类 )实现AppleKnife,TomatoKinfe
  3. CookLi(李厨师类)实现TomatoKinfe,PotatoKnife
  4. FruitShop(水果店类)cutApple方法和cutTomato方法分别传入AppleKnife和TomatoKinfe
  5. VegetableShop(蔬菜店类)cutTomato方法和cutPotato方法分别传入TomatoKinfe和PotatoKnife

public class SegregationDemo {
    public static void main(String[] args) {
        //水果店类
        new FruitShop().cutApple(new CookZhang());
        new FruitShop().cutTomato(new CookZhang());
        //蔬菜店类
        new VegetableShop().cutTomato(new CookLi());
        new VegetableShop().cutPotato(new CookLi());
    }
}

//示例接口隔离原则
// 将接口knife拆分为三个独立的接口
interface AppleKnife {
    //切苹果的能力
    void cutApple();

}
interface TomatoKinfe{
    //切番茄的能力
    void cutTomato();
}
interface PotatoKnife{
    //切土豆的能力
    void cutPotato();
}

//张厨师类
class CookZhang implements AppleKnife,TomatoKinfe {

    @Override
    public void cutApple() {
        System.out.println("张厨师正在切苹果");
    }

    @Override
    public void cutTomato() {
        System.out.println("张厨师正在切番茄");
    }


}

//李厨师类
class CookLi implements TomatoKinfe,PotatoKnife {

    @Override
    public void cutTomato() {
        System.out.println("李厨师正在切番茄");
    }

    @Override
    public void cutPotato() {
        System.out.println("李厨师正在切土豆");
    }
}

/*假设有这样一个案例场景,现在有一个接口knife,给定他有三个能力,可以切苹果,切番茄,切土豆,
两个类张厨师,李厨师分别具有这些能力,有一个水果店类,假设是需要张师傅来切苹果和切番茄,而另一个蔬菜店类需要
李师傅来切番茄和切土豆*/
//水果店类
class FruitShop {
    // 将接口类型作为参数传入
    public void cutApple(AppleKnife knife) {
        knife.cutApple();
    }

    public void cutTomato(TomatoKinfe knife) {
        knife.cutTomato();
    }
}

//蔬菜店类
class VegetableShop {

    public void cutTomato(TomatoKinfe knife) {
        knife.cutTomato();
    }

    public void cutPotato(PotatoKnife knife) {
        knife.cutPotato();
    }
}

案例总结

接口隔离原则就是当我一个类通过接口依赖(使用)另一个类的时候,要保证依赖的该接口是最小的,
接口里面有方法用不到的,就进行隔离,而隔离的做法就是,就对原来接口进行拆分,拆分为最小粒度,来避免耦合

三 与单一职责原则对比

单一职责原则:合理的职责分解,一个类只负责一项职责
接口隔离原则:类间的依赖关系应该建立在最小的接口上

相同点
都要求对结构进行拆分,都要求更小的粒度,都希望减少耦合

不同点
审视角度的不同

单一职责原则:类与接口职责单一,注重的是职责
接口隔离原则:要求我们尽量使用多个专门的接口,注重的是接口的设计

我们使用接口隔离原则进行接口拆分的时候,要遵循单一职责原则

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

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

相关文章

docker安装seata单节点的详细教程

一、环境部署 1、在自己的数据库新建seata数据库 2、利用seata官方提供的seata数据库sql脚本创建所需数据库seata以及表,脚本地址如下: seata/mysql.sql at 1.4.1 seata/seata GitHub 3、查看docker官方镜像仓库版本 4、拉取seata安装镜像 docker…

【机器学习实战】基于代价敏感学习的AdaCost方法用于信用卡欺诈检测

1. 数据集 数据集地址:Credit Card Fraud Detection 数据集整体浏览: 284807个样本,30个特征,1个分类标签Class Class为0的是多数类,一共有284315个样本。 Class为1的是少数类,一共有492个样本&#xff…

写给Python社群的第11课:Python线程,进程,协程,3个毫无关系的兄弟

文章目录⛳️ 线程、进程与协程🔥 进程与线程简介⛳️ Python 多线程模块🔥 threading 模块🔥 threading 模块实践⛳️ Python 并发进程模块🔥 Process 创建多进程⛳️ 线程、进程与协程 线程、进程、协程 这三个名称相似的概念&…

大话设计模型 Task03:工厂、制造、观察

目录一、建造者模式问题描述问题分析模式定义代码实现二、观察者模式问题描述问题分析模式定义代码实现一、建造者模式 问题描述 我的要求是你用程序画一个小人,这在游戏程序里非常常见,现在简单一点,要求是小人要有头、身体、两手、两脚就可…

左偏树原理详解

一 点睛 左偏树(leftist tree 或 leftist heap)也叫作左偏堆、左倾堆、左式堆,是计算机科学中的一种树,也是一种优先队列实现方式,属于可并堆,在信息学中十分常见,在统计、最值、模拟、贪心等类…

Win11安装WSL2和Nvidia驱动(2022-12-19)

文章目录前言系统环境WSL 1和WSL 2功能对比安装WSL2更新和升级包配置VSCode配置GPU加速安装Nvidia驱动安装Cuda Toolkit通过PyTorch安装CUDA Toolkit测试Nvcc参考链接前言 以前捣鼓过wsl,即Windows下的Linux子系统,但兼容性依然比不过原生的Linux系统&a…

【Linux】进程间通信之管道

目录🌈前言🌸1、IPC介绍🍢1.1、进程间通信的目的🍡1.2、背景和发展🍠1.3、进程间通信的分类🌷2、管道🍡2.1、概念🍢2.2、管道的原理🍣2.3、匿名管道🍤2.4、管…

DOM算法系列004-判断给定节点是否为body元素

UID: 20221218221939 aliases: tags: source: cssclass: created: 2022-12-18 如果我们要判定给定的一个节点是不是页面body与元素节点,该如何判断呢? 一般来说, 一个HTML页面内只有一个body元素 但是,如果我们非要在页面内写超过…

Spring boot 整合 redis

Spring boot 整合 redis一、Spring boot 整合redis1.1 启动redis1.2 redis desktop manager1.3 常用命令二、操作2.1 依赖包2.2 配置2.3 简单测试2.4 StringRedisTemplate一、Spring boot 整合redis 1.1 启动redis 命令行启动 redis-server redis-cli1.2 redis desktop mana…

基于electronbot作品bootLoader设计

文章目录 前言 一、芯片程序区规划和流程 1、flash区规划 2、两区运行流程 3、bootLoader代码体现 4、electronbot代码体现: 二、bootLoader代码设计 1.下载程序步骤 2.通讯协议格式 三、libusb开发及需要注意的事情 1、bootLoader复合设备 2、electronbot复合设备…

基础算法系列--[基本数据结构KMP]

文章目录前言链表单链表双链表栈和队列栈队列单调KMP前言 今天要搞的是基本的一些数据结构,当然咱们这个不是那么“正经”。当然今天也没啥代码,因为太简单了(其实我也想水一下~) 链表 单链表 单链表这个东西,应该…

Prometheus+Grafana

K8S prometheusK8S1.Prometheus(普罗米修斯)2.Prometheus可以做什么3.Prometheus的特点4.prometheus 相关组件二、prometheus与zabbix的区别zabbix架构区别三、prometheus架构分析1.TSDB2.时间序列数据库的特点3.prometheus 相关组件1.prometheus 核心组…

【计算机网络】实验五 网络层与链路层协议分析(PacketTracer)

一、实验目的 通过本实验,进一步熟悉PacketTracer的使用,学习路由器与交换机的基本配置,加深对网络层与链路层协议的理解。 二、实验内容: 4.1 路由器交换机的基本配置 打开下面的实验文件,按提示完成实验。 4.2…

直流微电网中潮流(Matlab代码实现)

目录 1 概述 1.1 直流电网中的潮流 1.2 创新点和相关工作 1.3 本文结构 2 数学/网络模型 2.1 主-从操作 2.2 孤岛运行 3 牛顿法 4 案例及Matlab代码实现 1 概述 潮流是一个非线性问题,需要用牛顿法求解具有恒定功率端子的直流微电网。本文提出了牛顿法在…

曙光来临!Nature终于发现了新冠特效药?或将彻底终结新冠时代!

百趣代谢组学文献分享:2022年即将过去,随着疫苗的全面接种和三年以来“动态清零”的坚持,我们在应对新冠病毒如潮水般的攻击中取得了阶段性成果。虽然大家陆陆续续投入到正常的工作生活中,但是我们都知道新冠并未被“打败”&#…

MySQL中这14个有用的小知识,快学起来吧

前言 我最近用MYSQL数据库挺多的,发现了一些非常有用的小玩意,今天拿出来分享到大家,希望对你会有所帮助。 1.group_concat 在我们平常的工作中,使用group by进行分组的场景,是非常多的。 比如想统计出用户表中&…

如何在产品开发中讨论概念设计?

每当你看到一辆在路上行驶的汽车、书桌上的笔记本电脑、工业包装生产线、医院设备、家用仪器和其他形式的概念设计创意产品会感到难以置信,这就是我们在产品开发中讨论概念设计的原因。 概念设计是一个尚未解决或到目前为止尚未令人满意的问题。这是一个深思熟虑的解…

研究区域制图 | 在 ArcGIS Pro中创建地图布局

研究区域制图 | 在 ArcGIS Pro中创建地图布局 数据准备 首先需要两个图层,一个是市区图层,一个是省行政区划图层,我这里以吉林省以及吉林省长春市为例 新建布局 选择横向A5即可 添加参考线 不知道你们知不知道这个功能,反正小…

kotlin协程笔记:Dispatchers

Kotlin 的 launch 会调用 startCoroutineCancellable(),接着又会调用 createCoroutineUnintercepted(),最终会调用编译器帮我们生成 SuspendLambda 实现类当中的 create() 方法。 public fun CoroutineScope.launch(context: CoroutineContext EmptyC…

【JVM】本地方法栈与堆与方法区

文章目录1. 本地方法栈2. 堆3. 方法区1. 本地方法栈 本地方法栈和虚拟机栈有点类似,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。 但是不同之处在于本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM…