草庐IT

贯穿设计模式第五话--接口隔离原则

最爱吃鱼罐头 2023-06-10 原文

🥳🥳🥳 茫茫人海千千万万,感谢这一刻你看到了我的文章,感谢观赏,大家好呀,我是最爱吃鱼罐头,大家可以叫鱼罐头呦~🥳🥳🥳

从今天开始,将开启一个专栏,【贯穿设计模式】,设计模式是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。为了能更好的设计出优雅的代码,为了能更好的提升自己的编程水准,为了能够更好的理解诸多技术的底层源码, 设计模式就是基石,万丈高楼平地起,一砖一瓦皆根基。 ✨✨欢迎订阅本专栏✨✨

🥺 本人不才,如果文章知识点有缺漏、错误的地方 🧐,也欢迎各位人才们评论批评指正!和大家一起学习,一起进步! 👀

❤️ 愿自己还有你在未来的日子,保持学习,保持进步,保持热爱,奔赴山海! ❤️

💬 最后,希望我的这篇文章能对你的有所帮助! 🍊 点赞 👍 收藏 ⭐留言 📝 都是我最大的动力!

📃 前言回顾


​ 🔥【贯穿设计模式】第一话·设计模式初介绍和单一职责原则🔥

​ 🔥【贯穿设计模式】第二话·设计模式的七大原则之开闭原则🔥

​ 🔥【贯穿设计模式】第三话·设计模式的七大原则之依赖倒转🔥

​ 🔥【贯穿设计模式】第四话·设计模式的七大原则之里氏替换🔥

在第四篇文章中,我们了解设计模式的七大原则中第四个原则: 里氏替换原则;

我们来回顾下,它的定义:任何基类可以出现的地方,子类一定可以出现,即所有引用基类的地方都必须能够透明的使用其子类;里氏替换原则是继承与复用的基石,只有当子类可以替换掉基类,且系统的功能不受影响时,基类才能被复用,而子类也能够在基础类上增加新的行为;所以里氏替换原则指的是任何基类可以出现的地方,子类一定可以出现

并且我们通过动物鸟类中,不同鸟类有会飞的和不会飞的,如果都定义一个飞翔代码,在继承的过程就会导致重写父类的方法导致违反了里氏替换原则了,

值得注意的是:在实现里氏替换原则过程中,常常可以通过依赖、聚合,组合等关系代替c

🦀接口隔离原则

今天我们学习的是接口隔离原则,一个类不应该依赖它不需要的接口。

🦞概述

  • 该原则是指一个类不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最少接口上;
  • 根据接口隔离原则拆分接口时,首先必须满足单一职责原则,而使用接口隔离,也能提高系统的高内聚;
  • 简单理解就是使用多个隔离的接口,比使用单个接口要好,即要为各个类建立它们需要的专用接口,不要为了省事而试图去建立一个很庞大的接口供所有依赖它的类去调用,并且这是一个能降低类之间的耦合度;
  • 比如有一个接口A,它其中有5个方法,现在类B需要用到接口A的三个方法,所以B类直接实现了接口A的全部方法,这就导致了B类多了两个不需要的方法,接口A对于类B来说并不是最小接口了,此时应该将臃肿的接口A拆分为独立的几个接口,类B与需要的接口建立依赖关系即可,也就是采用接口隔离原则。

🦐特点

接口隔离原则是强调接口的方法尽量少,尽量细化接口,通过接口隔离原则可以使系统有以下优点

  • 可以降低类与类之间的耦合性;

  • 提高系统的稳定性;

  • 提高代码的可扩展性和可维护性;

  • 提高系统的高内聚。

🦑问题引出

还记得在初中的时候,还有上着音乐课这些艺术课,每每上音乐课这些艺术课时,感觉都是非常快乐滴!还记得以前音乐课时,老师弹着稻香的钢琴,我们同学大家都在合唱着“还记得你说家是唯一的城堡,随着稻香河流继续奔跑,微微笑,小时候的梦我知道~~~”但是这些快乐后面慢慢就消散了,被各种需要中考,高考等等需要大量的学习必修课后替代了。接下来我们就以不同年级时不同课程来讲解下接口隔离原则吧。

1. 建立一个初中的中学的课程类:

先建立一个大概包含初中所有年级的课程

package com.ygt.principle.isp;

/**
 * 初中课程,包含着各中初中相关课程
 */
public interface JuniorHighCourse {

    // 初中当然有语数英啦,这里就写数学了,毕竟就数学学得好点哈哈
    void mathematics();

    // 还有一些其他必修课如 历史,地理,物理等这里就写物理啦
    void physics();

    // 还有一些艺术课可以上 如 音乐美术等,这里写音乐课,毕竟画画不行哈哈
    void music();
}

2. 建立一个初中学生去学习初中课程:

初中学生去学习初中课程,没毛病老铁~

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("我爱上音乐课~");
    }
}

3. 建立一个测试类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();
    }
}

4. 得到的结果:

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();
}

2. 重新建立不同年级学生接收想要的课程:

张三

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("李四最爱上物理课了,老子李四最偏科,只偏爱美术课~");
    }
}

3. 测试一下不同学生上不同课程:

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();
    }
}

4. 得到的结果:

张三不爱上数学课,张三只爱美女老师~
张三最不喜欢上物理课,就没有个美女物理老师吗~
张三最爱上音乐课,音乐老师唱歌真好听~
李四最爱上数学课了,老子李四数学排名全校第一~
李四最爱上物理课了,老子李四最偏科,只偏爱美术课~

这样我们将初中课程隔离出来,成立不同的课程接口,这样每个年级的学生都能学习当前年级应该学习的课程啦,这就体现了一个类对另一个类的依赖应该建立在最少接口上,不会出现空实现的状态,当然工作中,不可能将接口中每个方法都隔离出现,毕竟写一个接口就一个方法也不现实,只要表明该接口是处于什么角色,即应该拥有什么职责即可。

🌸 完结

相信各位看官看到这里大致都对设计模式中的其中一个原则有了了解吧,接口隔离原则指一个类不应该依赖它不需要的接口,表明该接口是处于什么角色,即应该拥有什么职责即可。

学好设计模式,让你感受一些机械化代码之外的程序设计魅力,也可以让你理解各个框架底层的实现原理。最后,祝大家跟自己能在程序员这条越走越远呀,祝大家人均架构师,我也在努力。 接下来期待第六话:迪米特法则。 💪💪💪

文章的最后来个小小的思维导图:

🧐 本人不才,如有什么缺漏、错误的地方,也欢迎各位人才们评论批评指正!🤞🤞🤞

🤩 当然如果这篇文章确定对你有点小小帮助的话,也请亲切可爱的人才们给个点赞、收藏下吧,非常感谢!🤗🤗🤗

🥂 虽然这篇文章完结了,但是我还在,永不完结。我会努力保持写文章。来日方长,何惧车遥马慢!✨✨✨

💟 感谢各位看到这里!愿你韶华不负,青春无悔!让我们一起加油吧! 🌼🌼🌼

💖 学到这里,今天的世界打烊了,晚安!🌙🌙🌙

有关贯穿设计模式第五话--接口隔离原则的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  6. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  7. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  8. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  9. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

  10. ruby-on-rails - 设计注册确认 - 2

    我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:

随机推荐