Java设计模式:一、六大设计原则-05:接口隔离原则
文章目录
- 一、定义:接口隔离原则
- 二、模拟场景:接口隔离原则
- 三、违背方案:接口隔离原则
- 3.1 工程结构
- 3.2 英雄技能调用
- 3.2.1 英雄技能接口
- 3.2.2 英雄:后裔
- 3.2.3 英雄:廉颇
- 3.3 单元测试
- 四、改善代码:接口隔离原则
- 4.1 工程结构
- 4.2 英雄分配英雄技能
- 4.2.1 射箭接口
- 4.2.2 隐袭接口
- 4.2.3 沉默
- 4.2.4 晕眩
- 4.2.5 英雄后裔的实现
- 4.2.6 英雄廉颇的实现
- 4.3 单元测试
一、定义:接口隔离原则
- 接口隔离原则:
Interface Segregation Principle,ISP。- 客户端不应该被迫依赖于它不使用的方法。
- 另一个定义:一个类对另一个类的依赖应该建立在最小的接口上。
- 接口隔离原则要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口只包含客户感兴趣的方法。
- 接口隔离是为了 高内聚、低耦合。
- 在实际的业务开发中,通常会先定义好需要开发的接口,并由各个服务类实现。
- 但如果没有经过考虑和设计,就很可能造成一个接口中包括众多的接口方法,而这些接口并不一定在每一个类中都需要实现。
- 这样的接口很难维护,也不易于扩展,每一次修改验证都有潜在的风险。
- 在具体应用接口隔离原则时,应该根据一下几个规则衡量。
- 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。
- 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。
- 了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同,要深入了解业务逻辑。
- 提高内聚,减少对外交互。让接口用最少的方法完成最多的事情。
二、模拟场景:接口隔离原则
- 《王者荣耀》里有很多英雄,可以分为射手、战士、刺客等,每个英雄有三种技能。
- 这些技能该如何定义,让每个英雄实现相应的技能效果呢?
三、违背方案:接口隔离原则
3.1 工程结构
design-1.5-0
|——src|——main|--java|--com.lino.design|--HeroHouYi.java|--HeroLianPo.java|--ISkill.java|——test|--java|--com.lino.design.test|--ApiTest.java
3.2 英雄技能调用
3.2.1 英雄技能接口
ISkill.java
package com.lino.design;/*** @description: 英雄技能接口*/
public interface ISkill {/*** 射箭*/void doArchery();/*** 隐袭*/void doInvisible();/*** 沉默*/void doSilent();/*** 眩晕*/void doVertigo();
}
- 定义一个技能接口,实现的英雄都需要实现这个接口,进而实现自己的技能。
- 这里提供了四个技能的接口,包括射箭、隐袭、沉默、晕眩,每个英雄都实现这个接口。接下来实现两个英雄:后裔和廉颇。
3.2.2 英雄:后裔
HeroHouYi.java
package com.lino.design;/*** @description: 英雄:后裔*/
public class HeroHouYi implements ISkill {@Overridepublic void doArchery() {System.out.println("后裔的灼日之矢");}@Overridepublic void doInvisible() {System.out.println("后裔的隐身技能");}@Overridepublic void doSilent() {System.out.println("后裔的沉默技能");}@Overridepublic void doVertigo() {// 无此技能的实现}
}
- 在英雄后裔的类中,实现了三个技能,最后一个晕眩的技能是不需要实现的。
3.2.3 英雄:廉颇
HeroLianPo.java
package com.lino.design;/*** @description: 英雄:廉颇*/
public class HeroLianPo implements ISkill {@Overridepublic void doArchery() {// 无此技能的实现}@Overridepublic void doInvisible() {System.out.println("廉颇的隐身技能");}@Overridepublic void doSilent() {System.out.println("廉颇的沉默技能");}@Overridepublic void doVertigo() {System.out.println("廉颇的眩晕技能");}
}
- 在英雄廉颇的类中,同样只实现了三个技能,有一个射箭的技能没有实现。
3.3 单元测试
ApiTest.java
@Test
public void test_ISKill() {// 后裔HeroHouYi heroHouYi = new HeroHouYi();heroHouYi.doArchery();// 廉颇HeroLianPo heroLianPo = new HeroLianPo();heroLianPo.doInvisible();
}
测试结果
后裔的灼日之矢
廉颇的隐身技能
- 综上,每个英雄的实现类里都有一个和自己无关的接口实现类,非常不符合设计模式,也不易于维护。
- 因为不仅无法控制外部的调用,还需要维护对应的文档,来说明这个接口不需要实现。如果由更多这样的接口,就会变得非常麻烦。
四、改善代码:接口隔离原则
4.1 工程结构
design-1.5-1
|——src|——main|--java|--com.lino.design|--impl| |-HeroHouYi.java| |-HeroLianPo.java|--ISkillArchery.java|--ISkillInvisible.java|--ISkillSilent.java|--ISkillVertigo.java|——test|--java|--com.lino.design.test|--ApiTest.java
4.2 英雄分配英雄技能
- 按照接口隔离原则的约定,应该在确保合理的情况下,把接口细分。保证一个松散的结构,也就是把技能拆分出来,每个英雄都可以按需继承实现。
- 接下来分别定义四个技能接口,包括:
- 射箭:
ISkillArchery - 隐身:
ISkillInvisible - 沉默:
ISkillSilent - 晕眩:
ISkillVertigo
- 射箭:
4.2.1 射箭接口
ISkillArchery.java
package com.lino.design;/*** @description: 射箭技能*/
public interface ISkillArchery {/*** 射箭*/void doArchery();
}
4.2.2 隐袭接口
ISkillInvisible.java
package com.lino.design;/*** @description: 影袭技能*/
public interface ISkillInvisible {/*** 隐袭*/void doInvisible();
}
4.2.3 沉默
ISkillSilent.java
package com.lino.design;/*** @description: 沉默技能*/
public interface ISkillSilent {/*** 沉默*/void doSilent();
}
4.2.4 晕眩
ISkillSilent.java
package com.lino.design;/*** @description: 晕眩技能*/
public interface ISkillVertigo {/*** 眩晕*/void doVertigo();
}
4.2.5 英雄后裔的实现
HeroHouYi.java
package com.lino.design.impl;import com.lino.design.ISkillArchery;
import com.lino.design.ISkillInvisible;
import com.lino.design.ISkillSilent;/*** @description: 英雄:后裔*/
public class HeroHouYi implements ISkillArchery, ISkillInvisible, ISkillSilent {@Overridepublic void doArchery() {System.out.println("后裔的灼日之矢");}@Overridepublic void doInvisible() {System.out.println("后裔的隐身技能");}@Overridepublic void doSilent() {System.out.println("后裔的沉默技能");}
}
4.2.6 英雄廉颇的实现
HeroLianPo.java
package com.lino.design.impl;import com.lino.design.ISkillInvisible;
import com.lino.design.ISkillSilent;
import com.lino.design.ISkillVertigo;/*** @description: 英雄:廉颇*/
public class HeroLianPo implements ISkillInvisible, ISkillSilent, ISkillVertigo {@Overridepublic void doInvisible() {System.out.println("廉颇的隐身技能");}@Overridepublic void doSilent() {System.out.println("廉颇的沉默技能");}@Overridepublic void doVertigo() {System.out.println("廉颇的眩晕技能");}
}
4.3 单元测试
ApiTest.java
@Test
public void test_ISKill() {// 后裔HeroHouYi heroHouYi = new HeroHouYi();heroHouYi.doArchery();// 廉颇HeroLianPo heroLianPo = new HeroLianPo();heroLianPo.doInvisible();
}
测试结果
后裔的灼日之矢
廉颇的隐身技能
- 现在可以看到这两个英雄的类都按需实现了自己需要的技能接口。
- 这样的实现方式就可以避免一些本身不属于自己的技能还需要不断地用文档的方式进行维护,同时提高了代码的可靠性,在别人接手或者修改时,可以降低开发成本和维护风险。
相关文章:
Java设计模式:一、六大设计原则-05:接口隔离原则
文章目录 一、定义:接口隔离原则二、模拟场景:接口隔离原则三、违背方案:接口隔离原则3.1 工程结构3.2 英雄技能调用3.2.1 英雄技能接口3.2.2 英雄:后裔3.2.3 英雄:廉颇 3.3 单元测试 四、改善代码:接口隔离…...
第63步 深度学习图像识别:多分类建模误判病例分析(Tensorflow)
基于WIN10的64位系统演示 一、写在前面 上两期我们基于TensorFlow和Pytorch环境做了图像识别的多分类任务建模。这一期我们做误判病例分析,分两节介绍,分别基于TensorFlow和Pytorch环境的建模和分析。 本期以健康组、肺结核组、COVID-19组、细菌性&am…...
OpenCv读/写视频色差 方案
OpenCv read / write video color differenceOpenCv读/写视频色差 感谢博主: OpenCv读/写视频色差答案 - 爱码网 有没有办法让 OpenCV 使用正确的转换?? 是的,使用 GStreamer 后端而不是 FFmpeg 后端,颜色看起来很完…...
【传输层】网络基础 -- UDP协议 | TCP协议
再谈端口号端口号范围划分netstatpidof UDPUDP的特点面向数据报UDP的缓冲区 基于UDP的应用层协议 TCP认识TCP协议的报头理解封装解包理解可靠性TCP工作模式16位窗口大小6位标志位URGACKPSHRSTSYNFIN 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序 在TCP/I…...
Android开发之性能测试工具Profiler
前言 性能优化问题,在我们开发时都会遇到,但是在小厂和对自己要求不严格的情况下,我都很少去做性能优化; 在性能优化上,基本大家都是通过自己的开发经验和性能分析工具来发现问题,今天给大家分享一下小编最…...
SpringBoot初级开发--多环境配置的集成(9)
在Springboot的开发中,我们经常要切换各种各样的环境配置,比如现在是开发环境,然后又切换到生产环境,这个时候用多环境配置就是一个明智的选择。接下来我们沿用上一章的工程来配置多环境配置工程。 1.准备多环境配置文件 这里我…...
(数学) 剑指 Offer 39. 数组中出现次数超过一半的数字 ——【Leetcode每日一题】
❓ 剑指 Offer 39. 数组中出现次数超过一半的数字 难度:简单 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输…...
如何用PS把roughness贴图转换成Smoothness,并放入Metallic贴图的a通道。
1:用PS打开Roughness贴图 2:选择反相,装换成Smoothness贴图 3:新建一个大小相等的psd文件,或者打开Metallic贴图 4:如果没有金属度贴图,就把新建的图画成纯黑色 5:选择图层蒙版->…...
了解XSS攻击与CSRF攻击
什么是XSS攻击 XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的网络安全漏洞,它允许攻击者在受害者的浏览器上执行恶意脚本。这种攻击通常发生在 web 应用程序中,攻击者通过注入恶意脚本来利用用户对网站的信任&…...
安全测试-django防御安全策略
django安全性 django针对安全方面有一些处理,学习如何进行处理设置,也有利于学习安全测试知识。 CSRF 跨站点请求伪造(Cross-Site Request Forgery,CSRF)是一种网络攻击方式,攻击者欺骗用户在自己访问的网…...
7.react useReducer使用与常见问题
useReducer函数 1. useState的替代方案.接收一个(state, action)>newState的reducer, 并返回当前的state以及与其配套的dispatch方法2. 在某些场景下,useReducer会比useState更加适用,例如state逻辑较为复杂, 且**包含多个子值**,或者下一个state依赖于之前的state等清楚us…...
c#泛型(generic)
概述: C#中的泛型(Generics)是一种允许在编写类、方法和委托时使用参数化类型的机制。泛型允许我们编写更通用、可重用的代码,可以避免类型转换和重复编写类似的代码。 泛型的基本语法如下所示: class ClassName<…...
【力扣每日一题】2023.8.30 到家的最少跳跃次数
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一只跳蚤,我们可以操控它前跳 a 格或是后跳 b 格,不能跳到小于0的位置,有一些被禁止的点不…...
精读《算法题 - 地下城游戏》
今天我们看一道 leetcode hard 难度题目:地下城游戏。 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士…...
随记-Kibana Dev Tools,ES 增删改查 索引,Document
索引 创建索引 创建索引 PUT index_test创建索引 并 修改分片信息 # 创建索引 并 修改分片信息 PUT index_test2 { # 必须换行, PUT XXX 必须独占一行,类似的 其他请求也需要独占一行 "settings": {"number_of_shards": 1, # 主分片"…...
什么是架构,架构的本质是什么
不论是开发人员还是架构师,我们都一直在跟软件系统打交道,架构是在工作中出现最频繁的术语之一。那么,到底什么是架构?你可能有自己的答案,也有可能没有答案。对“架构”的理解需要我们不断在实践中思考、归纳、演绎&a…...
Python爬虫(十七)_糗事百科案例
糗事百科实例 爬取糗事百科段子,假设页面的URL是: http://www.qiushibaike.com/8hr/page/1 要求: 使用requests获取页面信息,用XPath/re做数据提取获取每个帖子里的用户头像连接、用户姓名、段子内容、点赞次数和评论次数保存到json文件内…...
Ae 效果:CC Threads
生成/CC Threads Generate/CC Threads CC Threads(CC 编织条)效果基于当前图层像素生成编织条图案和纹理。可以用在各种设计中,如背景设计、图形设计、文字设计等。 ◆ ◆ ◆ 效果属性说明 Width 宽度 设置编织的宽度。 默认值为 50。值越大…...
Kotlin 协程 - 多路复用 select()
一、概念 又叫选择表达式,是一个挂起函数,可以同时等待多个挂起结果,只取用最快恢复的那个值(即多种方式获取数据,哪个更快返回结果就用哪个)。 同时到达 select() 会优先选择先写子表达式,想随…...
学习笔记-ThreadLocal
ThreadLocal 什么是ThreadLocal? ThreadLocal 是线程本地变量类,在多线程并行执行过程中,将变量存储在ThreadLocal中,每个线程中都有独立的变量,因此不会出现线程安全问题。 应用举例 解决线程安全问题:例…...
B站成分检测器:3分钟快速识别评论区同好身份
B站成分检测器:3分钟快速识别评论区同好身份 【免费下载链接】bilibili-comment-checker B站评论区自动标注成分油猴脚本,主要为原神玩家识别 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-comment-checker 还在为B站评论区难以分辨用户…...
IDEA 好用的ai插件 Windsurf
文章目录 前言一、Windsurf 插件功能二、IDEA安装三、登录Windsurf四、Windsurf简单使用介绍 前言 在 IntelliJ IDEA 中,Windsurf 是一款专注于 AI 代码辅助的插件,能够提升开发效率。以下是关于该插件的关键信息和使用方法: 提示࿱…...
Qwen3.5-2B图文对话实战:上传实验数据图→自动识别坐标轴+趋势分析+结论建议
Qwen3.5-2B图文对话实战:上传实验数据图→自动识别坐标轴趋势分析结论建议 1. 引言:当AI遇见科研数据分析 作为一名科研工作者,你是否经常遇到这样的场景:实验室刚跑出一组数据,你迫不及待想分析趋势,却发…...
Realistic Vision V5.1 提示词工程入门:C语言基础思维在Prompt编写中的应用
Realistic Vision V5.1 提示词工程入门:C语言基础思维在Prompt编写中的应用 如果你有C语言的编程经验,现在想玩转AI图像生成,特别是像Realistic Vision V5.1这样的写实风格模型,那这篇文章就是为你准备的。很多人觉得写提示词&am…...
知乎上线求职工具,助力毕业生破困局
知乎上线求职利器,直击毕业生痛点2026届全国普通高校毕业生预计达1270万人,再创历史新高。与此同时,AI技术加速行业重构,部分传统岗位需求收缩,大量毕业生陷入“海投”困境,难以精准定位自身。在此背景下&a…...
【读书笔记】《在远远的背后带领》
《在远远的背后带领》书话整理书名由来 "在远远的背后带领"这个书名,源于作者对十余年养育实践的回顾与思考。她发现,父母养育孩子容易走两个极端: 过度控制:强迫孩子按照自己的想法行事,结果双方俱疲&#…...
Gitee团队协作实战:从零到一掌握项目协同开发流程
1. 为什么选择Gitee进行团队协作开发 作为一个经历过多次团队协作开发的老手,我强烈推荐Gitee作为国内团队的代码托管平台。相比其他平台,Gitee的服务器在国内,访问速度更快,而且完全符合国内开发者的使用习惯。记得我第一次带团队…...
OpenCV实战:3种图像降噪滤波器的Python代码对比(附效果图)
OpenCV实战:3种图像降噪滤波器的Python代码对比(附效果图) 在数字图像处理中,噪声是影响图像质量的主要因素之一。无论是来自传感器的不完美,还是传输过程中的干扰,噪声都会降低图像的清晰度和可用性。对于…...
FunASR Docker部署SSL配置的四个‘天坑’与避坑指南(附完整启动命令)
FunASR Docker部署SSL配置的四个‘天坑’与避坑指南(附完整启动命令) 在语音识别服务的安全部署中,SSL/TLS加密已成为行业标配。但当我们实际为FunASR配置HTTPS时,那些看似简单的步骤背后却暗藏玄机。本文将带您穿越四个最具迷惑性…...
协方差矩阵可视化指南:如何用Seaborn热力图解读变量关系(附完整代码)
协方差矩阵可视化指南:如何用Seaborn热力图解读变量关系(附完整代码) 在数据分析的实际工作中,我们常常需要向非技术背景的决策者解释复杂的统计结果。这时候,一张直观的热力图往往比几十页的统计报告更有说服力。协方…...
