设计模式原则-三-依赖倒转原则

news2025/1/11 12:36:29

设计模式原则---依赖倒转原则

  • 依赖倒转原则
    • 一 官方定义
      • 基本介绍
    • 二 案例演示
      • 普通方式实现
        • **解决方案**
        • **案例分析**
        • **案例总结**
      • 依赖倒转原则方式实现
        • **解决方案**
        • 案例分析
        • **案例总结**
      • 注意事项&细节
    • 三 依赖关系传递方式
      • 一、通过接口传递
      • 二、通过构造方法传递
      • 三、通过set()方法传递

依赖倒转原则

其实我们在实际的开发中大部分都是遵守依赖倒转原则。即面向接口编程,习惯成自然,不知所以然。通过这个分析明确出来,以后写代码时就明白了为什么这样写,同时就会有意的去遵守这些看似简单但却很重要的设计模式原则,降低耦合提高代码质量。

一 官方定义

  • 依赖倒转原则,又称依赖倒置原则(Dependence Inversion Principle),又称DIP原则,官方定义为:
    High level modules should not depend upon low level modules. Both should depend upon abstractions.
    (上层模块不应该依赖底层模块,它们都应该依赖于抽象)
    Abstractions should not depend upon details. Details should depend upon abstractions.
    (抽象不应该依赖于细节,细节应该依赖于抽象)

基本介绍

何为抽象? —> 接口或者抽象类
何为细节?—> 实现类
换句话说 依赖倒转原则核心的理念 相对于细节来说,抽象要稳定得多
要求我们 面向接口编程
java中抽象类和接口的目的就是制定好规范,不会涉及具体的操作 展现细节或者实现具体的业务逻辑,这些是要交给对应的实现类来解决的、换句话说抽象类和接口的价值就在于设计
总结: 依赖倒转原则其实就是要求我们面向接口编程,其实就是要求我们在编码的时候注意抽象类和接口的设计

二 案例演示

假设有这样一个场景 现在有一个工作人员,收发钉钉消息和微信消息,qq消息

普通方式实现

解决方案

在这里插入图片描述

案例分析

现在work接收的是钉钉消息,哪天比较忙接收微信,或者qq消息等等。那我们需要扩展功能的,那根据这样的实现逻辑就需要

  • 增加微信类并添加发送消息方法;
  • 增加qql类添加发送消息方法;
  • 在work类中新定义两个新的方法来接收微信和qq消息

案例总结

由传统案例看出我们不光需要新增类,work类中也需要新增相应的接收方法才可以,这显然比较笨重,维护性差的同时频繁修改代码也会带来意向不到的风险。
如果按照依赖倒转原则思想,使用接口为编程,对案例进行重构来看看什么效果。

依赖倒转原则方式实现

为了解决上述案例的弊端我们引入依赖倒转原则方式

解决方案

引入接口制定规范:定义 IMessage接口 来表示信息的接收者,钉钉,微信,qq都是消息接收的途径,就可以让他们实现该接口来完成具体的实现细节,然后work只需要与该接口发生关系即可。使用依赖倒转原则进行改造。

public class InversionDemo {

    public static void main(String[] args) {

        new Worker().getMessage(new WeChat());
        new Worker().getMessage(new Message());
        new Worker().getMessage(new DingDing());
    }
}

//案例演示 - 依赖倒转原则
//假设有这样一个场景 现在有一个工作人员,收发钉钉消息
//引入接口,制定消息的规范
interface IMessage {
    void SendMessage();
}

class Worker {
    //公共的接收消息方法
    public void getMessage(IMessage iMessage) {
        iMessage.SendMessage();
    }
}

//钉钉类
class DingDing implements IMessage {
    @Override
    public void SendMessage() {
        System.out.println("钉钉上,老板找你加班啦");
    }
}

//微信类
class WeChat implements IMessage {
    @Override
    public void SendMessage() {
        System.out.println("钉钉不会,老板给你打微信电话了");
    }
}

//qq类
class Message implements IMessage {
    @Override
    public void SendMessage() {
        //TODO...
    }
}

案例分析

定义一个接口为模板,让各种消息接收的途径去实现。这样的话如果说业务不光要求这三个,还有第四个第五个接收消息的方式,我们添加对应的实体类,实现接口就可以。work端是不需要变动和维护的。
在这里插入图片描述

案例总结

依赖倒转原则本质上 就是通过抽象(抽象类和接口)使得各个类或者模块实现彼此独立,互相不 影响,实现模块间松耦合,要先顶层再细节的方式来进行代码设计

其实我们在实际的开发中大部分都是面向接口编程,习惯成自然,不知所以然。通过这个分析明确出来,以后写代码时就明白了为什么这样写,同时就会有意的去遵守这些看似简单但却很重要的设计模式原则,降低耦合提高代码质量。

注意事项&细节

  • 低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好
  • 变量的声明类型尽量是抽象类或者接口,这样我们的变量引用和实际对象间,就存在一个缓冲层, 利于程序扩展和优化
  • 继承时遵循里式替换原则

三 依赖关系传递方式

一、通过接口传递

interface IMessage{

    void sendMessage(Produce produce);
}

//消息真正的生产者
interface Produce{

    void produceMessage();
}

class Worker implements IMessage{

    @Override
    public void sendMessage(Produce produce) {
        produce.produceMessage();
    }
}

二、通过构造方法传递

//通过构造器来传递
interface IMessage{

    void sendMessage();
}

//消息真正的生产者
interface Produce{

    void produceMessage();
}

class Worker implements IMessage{

    public Produce produce;

    public Worker(Produce produce){

        this.produce = produce;
    }

    @Override
    public void sendMessage() {
        this.produce.produceMessage();
    }
}

三、通过set()方法传递

//通过set()方法
interface IMessage{

    void sendMessage();
}

//消息真正的生产者
interface Produce{

    void produceMessage();
}

class Worker implements IMessage{

    public Produce produce;

    public void setProduce(Produce produce){
        this.produce = produce;
    }


    @Override
    public void sendMessage() {
        this.produce.produceMessage();
    }
}

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

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

相关文章

原来 Android 的 R 文件里还有这么多道道

前言 nonTransitiveRClass:非传递性 R 类的属性,在 gradle.properties 文件里使用。 不少开发者可能听过它,但了解可能仅限于是对 R 文件做了优化,甚至以为它可以解决资源冲突!但它到底做了什么优化、能否解决资源冲突…

Manacher算法

0、概括 Manacher算法用于求解字符串中最长回文子串问题。 Manacher算法的核心: 理解回文半径数组;理解所有中心的回文最右边界 R,和取得 R 时的中心点 C;理解 L...(i)...C...(i)...R 的结构,以及根据 i′ii′ 回文长…

C-RNN-GAN:具有对抗训练的连续循环神经网络2016--生成音乐

C-RNN-GAN: Continuous recurrent neural networks with adversarial training 2016 Abstract 生成对抗网络已被提出作为一种有效训练深度生成神经网络的方法。我们提出了一种生成对抗模型,它适用于连续的序列数据,并通过在古典音乐集合上训练它来应用它…

计算机毕设Python+Vue校园学生体温管理系统(程序+LW+部署)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

相见恨晚,Git这些功能太好用了

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 作为一名开发者,想必绝大多数同学都无法绕开Git。 作为一款工具,我认为它和word、powerpoint、Excel这些办公工具一样。 对于一部分同学,会一些基本的用法&#x…

【经验帖】项目经理的核心价值:以目标为导向做正确的事

项目经理小李的年终汇报心路历程(心情犹如坐过山车,起起落落最后一蹶不振。) 汇报前: 终于到年终汇报的日子了,毕竟我负责的项目任务从来没有延期过,都是按时完成,这次肯定得加薪了&#xff01…

[附源码]Node.js计算机毕业设计公租房管理系统Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

module命名空间

为什么要有namespaced命名空间? 默认情况下,模块内部的action、mutation和getter都是在全局命名空间。 假设两个modules内部有同名的action、mutation和getter,则vuex会报错。 namespaced作用:保证模块内部的高封闭性,…

021 | 阴离子诱导的系列双核镝配合物的合成及磁性质 | 大学生创新训练项目申请书 | 极致技术工厂

研究目的 近十几年来,随着科技的飞速发展,单分子磁体材料涉及的应用领域越来越宽广。众所周知,单分子磁体材料作为信息存储的基础对信息产业的发展具有一定的意义。此外,单分子磁体在超高密度储存、自旋电子器件、量子计算机等领域…

旅游住宿网站

开发工具(eclipse/idea/vscode等): 数据库(sqlite/mysql/sqlserver等): 功能模块(请用文字描述,至少200字): 网站前台:网站介绍、帮助信息、旅游资讯。景点信息、酒店信息 管理员功能: 1、管理网站介绍、帮…

day22【代码随想录】在每个树行中找最大值、填充每个节点的下一个右侧节点指针、二叉树的最大深度、二叉树的最小深度

文章目录前言一、在每个树行中找最大值(力扣515)二、填充每个节点的下一个右侧节点指针(力扣116)三、二叉树的最大深度(力扣104)1、非递归求解2、递归求解四、 二叉树的最小深度(力扣111&#x…

【前端开发学习】4.JavaScript

文章目录1 JavaScript1.1 代码位置1.2 存在形式1.3 注释1.4 变量1.5 字符串类型案例:走马灯1.5 数组案例:动态数据1.6 对象(字典)案例:动态表格1.7 条件语句1.8 函数2 DOM2.1 事件绑定1 JavaScript 一门编程语言&…

第二证券|主力加仓电子、电气设备等行业 北向资金连续2日净流入

沪深两市股市涨跌互现,上证指数早盘震动下探,午后一度回升,尾盘再度回落;深证成指早盘探底回升,午后震动上扬,尾盘有所回落;创业板指早盘窄幅震动,午后震动上扬;科创50指…

D. Say No to Palindromes(构造 + 前缀和)

Problem - 1555D - Codeforces 如果这个字符串不包含一个长度至少为2的子串,我们就称它为美丽的字符串,这是一个回文。回顾一下,回文是指从第一个字符到最后一个字符以及从最后一个字符到第一个字符的读法相同的字符串。例如,字符…

京东物流 × StarRocks : 打造服务分析一体化平台Udata

作者:张栋,京东物流集团数据专家 京东集团 2007 年开始自建物流,2017 年 4 月正式成立京东物流集团,2021 年 5 月,京东物流于香港联交所主板上市。京东物流是中国领先的技术驱动的供应链解决方案及物流服务商&#xff…

Linux内核

内核属于操作系统的核心部分,它具有操作系统基本的功能,主要负责管理系统的内存、进程、设备驱动程序、文件系统和网络接口,因此,操作系统的性能和稳定性由内核决定。 1、内存管理 进程对内存的使用 计算机中所有要执行的程序都必…

大厂10年经验,我对Java高并发问题方案的总结,堪称教科书级

作为一个 Java 开发人员,多线程是一个逃不掉的话题,不管是工作还是面试,但理解起来比较模糊难懂,因为多线程程序在跑起来的时候比较难于观察和跟踪。 搞懂多线程并发知识,可以在面试的时候和周围人拉开差距&#xff0…

流媒体:依托于声网的连麦解决方案

一、背景 近些年,直播连麦这把火在流媒体领域整整燃烧了 6 年。从刚开始的简单探索,到现在的成熟全链路方案,不得不说日益增长的激烈竞争,已将让原本的蓝海领域变成了深海互搏。在这样的大环境下,是否意味着小厂将再也…

分布式系统(P2P Lookup)

文章目录P2P 系统NapsterBitTorrentGnutellaChordConsistent HashingSimple Key LocationScalable Key LocationKademliaRouting TableKademlia’s RPCAdaptabilityDistributed Hash TableP2P 系统 Peer to peer 系统: 每个结点在连接上是互联的,在功能…

Spring MVC: 一种简洁且强大的Web应用框架

⭐️前言⭐️ 这篇文章介绍Spring MVC,Spring MVC是现在基本所有Java程序的主流开发框架,这篇文章主要介绍三部分内容: 实现用户和程序的映射(在浏览器输入URL地址之后,能够在程序中匹配到相应方法)。服务器端得到用户的请求参数…