贯穿设计模式第五话--接口隔离原则
🥳🥳🥳 茫茫人海千千万万,感谢这一刻你看到了我的文章,感谢观赏,大家好呀,我是最爱吃鱼罐头,大家可以叫鱼罐头呦~🥳🥳🥳
从今天开始,将开启一个专栏,
【贯穿设计模式】
,设计模式是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。为了能更好的设计出优雅的代码,为了能更好的提升自己的编程水准,为了能够更好的理解诸多技术的底层源码, 设计模式就是基石,万丈高楼平地起,一砖一瓦皆根基。 ✨✨欢迎订阅本专栏✨✨
🥺 本人不才,如果文章知识点有缺漏、错误的地方 🧐,也欢迎各位人才们评论批评指正!和大家一起学习,一起进步! 👀
❤️ 愿自己还有你在未来的日子,保持学习,保持进步,保持热爱,奔赴山海! ❤️
💬 最后,希望我的这篇文章能对你的有所帮助! 🍊 点赞 👍 收藏 ⭐留言 📝 都是我最大的动力!
📃 前言回顾
在第四篇文章中,我们了解设计模式的七大原则中第四个原则: 里氏替换原则;
我们来回顾下,它的定义:任何基类可以出现的地方,子类一定可以出现,即所有引用基类的地方都必须能够透明的使用其子类;里氏替换原则是继承与复用的基石,只有当子类可以替换掉基类,且系统的功能不受影响时,基类才能被复用,而子类也能够在基础类上增加新的行为;所以里氏替换原则指的是任何基类可以出现的地方,子类一定可以出现
并且我们通过动物鸟类中,不同鸟类有会飞的和不会飞的,如果都定义一个飞翔代码,在继承的过程就会导致重写父类的方法导致违反了里氏替换原则了,
值得注意的是:在实现里氏替换原则过程中,常常可以通过依赖、聚合,组合等关系代替c
🦀接口隔离原则
今天我们学习的是接口隔离原则,一个类不应该依赖它不需要的接口。
🦞概述
- 该原则是指一个类不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最少接口上;
- 根据接口隔离原则拆分接口时,首先必须满足单一职责原则,而使用接口隔离,也能提高系统的高内聚;
- 简单理解就是使用多个隔离的接口,比使用单个接口要好,即要为各个类建立它们需要的专用接口,不要为了省事而试图去建立一个很庞大的接口供所有依赖它的类去调用,并且这是一个能降低类之间的耦合度;
- 比如有一个接口A,它其中有5个方法,现在类B需要用到接口A的三个方法,所以B类直接实现了接口A的全部方法,这就导致了B类多了两个不需要的方法,接口A对于类B来说并不是最小接口了,此时应该将臃肿的接口A拆分为独立的几个接口,类B与需要的接口建立依赖关系即可,也就是采用接口隔离原则。
🦐特点
接口隔离原则是强调接口的方法尽量少,尽量细化接口,通过接口隔离原则可以使系统有以下优点:
- 可以降低类与类之间的耦合性;
- 提高系统的稳定性;
- 提高代码的可扩展性和可维护性;
- 提高系统的高内聚。
🦑问题引出
还记得在初中的时候,还有上着音乐课这些艺术课,每每上音乐课这些艺术课时,感觉都是非常快乐滴!还记得以前音乐课时,老师弹着稻香的钢琴,我们同学大家都在合唱着“还记得你说家是唯一的城堡,随着稻香河流继续奔跑,微微笑,小时候的梦我知道~”但是这些快乐后面慢慢就消散了,被各种需要中考,高考等等需要大量的学习必修课后替代了。接下来我们就以不同年级时不同课程来讲解下接口隔离原则吧。
- 建立一个初中的中学的课程类:
先建立一个大概包含初中所有年级的课程
package com.ygt.principle.isp;
/**
* 初中课程,包含着各中初中相关课程
*/
public interface JuniorHighCourse {
// 初中当然有语数英啦,这里就写数学了,毕竟就数学学得好点哈哈
void mathematics();
// 还有一些其他必修课如 历史,地理,物理等这里就写物理啦
void physics();
// 还有一些艺术课可以上 如 音乐美术等,这里写音乐课,毕竟画画不行哈哈
void music();
}
- 建立一个初中学生去学习初中课程:
初中学生去学习初中课程,没毛病老铁~
package com.ygt.principle.isp;
/**
* 建立一个初中学生去接收初中课程
* 一旦实现了初中课程,就包含了所有的初中课程了
*/
public class Ygt implements JuniorHighCourse {
@Override
public void mathematics() {
System.out.println("我爱上数学课~");
}
@Override
public void physics() {
System.out.println("我爱上物理课~");
}
@Override
public void music() {
System.out.println("我爱上音乐课~");
}
}
- 建立一个测试类ISPTest测试一下ygt的学习情况::
package com.ygt.principle.isp;
/**
* 接口隔离测试
*/
public class ISPTest {
public static void main(String[] args) {
// 创建一个初中学生鱼罐头学习初中课程
Ygt ygt = new Ygt();
ygt.mathematics();
ygt.physics();
ygt.music();
}
}
- 得到的结果:
package com.ygt.principle.isp;
/**
* 接口隔离测试
*/
public class ISPTest {
public static void main(String[] args) {
// 创建一个初中学生鱼罐头学习初中课程
Ygt ygt = new Ygt();
ygt.mathematics();
ygt.physics();
ygt.music();
}
}
我们都知道,初中是分多个年级的,而每个年级学习的课程是有所不同的,所以如果每个年级的学生都只是实现一个初中课程,那是不是在高年级时学习的课程就会颇多呢,甚至高年级是没有体育、音乐等课程的,所以如果去实现初中课程,就会导致原本的课程是个空实现,而且我们把这些课程都集成在初中课程中,这就会导致初中课程的接口所拥有的职责过多,这也导致违反了接口隔离原则了,所以我们必须把课程分出来,或者是将不同年级的课程分别出来。下面就一起来看看解决方案吧。
🐙解决方案
在接口隔离的核心中,我们清楚知道一个类不应该依赖它不需要的接口,所以我们可以将每个课程都隔离独立出来成立一个新接口,或者将不同年级的课程确定好,这样每个年级的学生都能得到自己想要的初中课程学习啦。
1 . 分别建立不同课程的接口:
数学课
package com.ygt.principle.isp;
/**
* 数学课
* 这个数学课,别说初中了,小学、高中、大学都还有呢
*/
public interface IMathematics {
void mathematics();
}
物理课
package com.ygt.principle.isp;
/**
* 物理课
* 高中都有物理课,别放弃,学好物理化,走遍天下都不怕!
*/
public interface IPhysics {
void physics();
}
音乐课
package com.ygt.principle.isp;
/**
* 音乐课
*/
public interface IMusic {
void music();
}
- 重新建立不同年级学生接收想要的课程:
张三
package com.ygt.principle.isp;
/**
* 建立一个初一的张三学习初一相关课程
* (当然,这里的课程不全,这做展示演示~)
*/
public class ZhangSan implements IMathematics, IPhysics, IMusic{
@Override
public void mathematics() {
System.out.println("张三不爱上数学课,张三只爱美女老师~");
}
@Override
public void music() {
System.out.println("张三最爱上音乐课,音乐老师唱歌真好听~");
}
@Override
public void physics() {
System.out.println("张三最不喜欢上物理课,就没有个美女物理老师吗~");
}
}
李四
package com.ygt.principle.isp;
/**
* 建立一个初三的李四学习初一相关课程
* 初三了,就没有音乐课这些啦~ 李四表示最喜欢上美术课,美术老师最好看~
* (当然,这里的课程不全,这做展示演示~)
*/
public class LiSi implements IMathematics, IPhysics{
@Override
public void mathematics() {
System.out.println("李四最爱上数学课了,老子李四数学排名全校第一~");
}
@Override
public void physics() {
System.out.println("李四最爱上物理课了,老子李四最偏科,只偏爱美术课~");
}
}
- 测试一下不同学生上不同课程:
package com.ygt.principle.isp;
/**
* 接口隔离测试
*/
public class ISPTest {
public static void main(String[] args) {
// 创建一个初中学生鱼罐头学习初中课程
/*Ygt ygt = new Ygt();
ygt.mathematics();
ygt.physics();
ygt.music();*/
// 有请此时的初一法外狂徒张三学习初一课程
ZhangSan zs = new ZhangSan();
zs.mathematics();
zs.physics();
zs.music();
// 有请初三的高年级李四学习初三课程
LiSi ls = new LiSi();
ls.mathematics();
ls.physics();
}
}
- 得到的结果:
张三不爱上数学课,张三只爱美女老师~
张三最不喜欢上物理课,就没有个美女物理老师吗~
张三最爱上音乐课,音乐老师唱歌真好听~
李四最爱上数学课了,老子李四数学排名全校第一~
李四最爱上物理课了,老子李四最偏科,只偏爱美术课~
这样我们将初中课程隔离出来,成立不同的课程接口,这样每个年级的学生都能学习当前年级应该学习的课程啦,这就体现了一个类对另一个类的依赖应该建立在最少接口上,不会出现空实现的状态,当然工作中,不可能将接口中每个方法都隔离出现,毕竟写一个接口就一个方法也不现实,只要表明该接口是处于什么角色,即应该拥有什么职责即可。
🌸 完结
相信各位看官看到这里大致都对设计模式中的其中一个原则有了了解吧,接口隔离原则指一个类不应该依赖它不需要的接口,表明该接口是处于什么角色,即应该拥有什么职责即可。
学好设计模式,让你感受一些机械化代码之外的程序设计魅力,也可以让你理解各个框架底层的实现原理。最后,祝大家跟自己能在程序员这条越走越远呀,祝大家人均架构师,我也在努力。 接下来期待第六话:迪米特法则。 💪💪💪
文章的最后来个小小的思维导图:
🧐 本人不才,如有什么缺漏、错误的地方,也欢迎各位人才们评论批评指正!🤞🤞🤞
🤩 当然如果这篇文章确定对你有点小小帮助的话,也请亲切可爱的人才们给个点赞、收藏下吧,非常感谢!🤗🤗🤗
🥂 虽然这篇文章完结了,但是我还在,永不完结。我会努力保持写文章。来日方长,何惧车遥马慢!✨✨✨
💟 感谢各位看到这里!愿你韶华不负,青春无悔!让我们一起加油吧! 🌼🌼🌼
💖 学到这里,今天的世界打烊了,晚安!🌙🌙🌙
转载自:https://juejin.cn/post/7227047563298783292