深入理解依赖反转原则(DIP)

依赖反转原则是一个比较重要的架构原则,从定义上看是要依赖于抽象,不要依赖于细节, 这个听起来很简单,好像加个接口就完事了,大家的service都是一个接口配一个实现类,是不是依赖倒置呢?很显然不是,不然今天就不用讲了

先举个例子,我们的应用会依赖很多三方的服务,DB、缓存、文件存储、短信邮件服务等等,拿缓存来说,假如使用的是redis缓存,java应用访问redis一般都会使用Jedis,如果我们的业务代码直接使用jedis,那就是依赖细节(如下图左侧),这时候公司要换技术栈,redis不用了,换成memcached,所有直接依赖JedisApi的业务代码全都得变,这就是直接依赖细节的问题:让业务层变得不太稳定

那应该怎么样保证业务层稳定呢?把依赖于细节变成依赖于抽象,业务层要的是redis吗?不!业务层要的示一个缓存服务,那就在业务层定义好缓存服务的接口,至于底层到底是redis还是memcached,业务层不关心(如上图右侧)

那谁来关心实现细节呢?外层关心,外层可以基于redis实现、也可以基于memcached实现,外层负责把业务层定义的知识(CacheService)和具体的三方服务的知识(JedisApi)互相转换、做个适配,所以这一层又叫做适配器层,如果要更换三方服务,也只是外层层变化,对业务层没有影响。

这里有个很关键的点就是,业务层定义的接口里不要有任何与细节相关的东西,不然就没有意义了,比如如果上图右侧的CacheService中还有jedis api里的东西,那就跟左侧没啥区别了,那就不叫依赖于抽象了,又变成依赖于细节了。

从依赖方向上看,上图左侧是业务层依赖于外层,右侧的依赖关系反过来了,变成了外层依赖于业务层,这就是依赖反转的本质。很明显右侧这种依赖方式,使得业务层可以保持稳定,因为规则是业务层定义的,外层只能去适配业务层定义的规则。

把依赖于redis这个例子泛化一点,应用会用到各种各样的三方服务,都是一个道理。

这样你就会发现,系统合理的依赖关系不太应该是这种从上到下的,因为领域层不应该直接依赖下面的基础设施,而应该是这种从外向内的依赖关系(这里我只画了两层同心圆,实际可能会有多层,但不妨碍我们理解)

越靠近中心,它的软件层次就越高,它越是核心业务逻辑,内部区域包含了所有的领域逻辑,而外部区域则包含了系统与外界交互的东西(比如web、rpc接口,以及数据库、文件服务、缓存这些基础设施)。不管是web、rpc还是db、cache,都是系统和外部系统交互的层,都在领域层的外层。

这里有一条非常重要的原则,就是它的依赖关系必须是外层依赖于内层,不能反过来,web层依赖于领域层,与底层设施交互的层也依赖于领域层,内层代码中不应该包含任何外层代码的知识,像类、函数、变量都不行。这样的好处很明显,业务逻辑可以保持纯净、独立,它是整个系统的核心,外层的这些东西对于业务逻辑来说都是插件,可以轻易被替换掉、并且对业务逻辑不产生影响

下面是一张六边形架构图,你会发现它要表达的意思跟前面说的是一个道理。最内层的是领域、业务逻辑,最外层的是客户端、用户、外部系统、下游基础设施

最关键的是它的依赖关系,是从外向内的,外层依赖于内层,外层了解内层的知识,反过来就不行 那怎么样保持这个依赖关系呢?用端口和适配器(所以六边形架构图又叫端口适配器架构,其实端口适配器架构更能表达它的主要思想)

端口其实就是接口,你看它端口都是在内层,意思是接口都由领域层定义,外层这一个个的适配器干嘛的呢,把外部的东西和领域层定义的互相转换,所以叫适配,这和我们前面说的是一个意思 

总结两点: 1:大家在做设计时,首先要明确内层外层的概念,核心业务逻辑就是内层的;2:有了内外层之分后,一个指导原则就是外层可以依赖内层,反过来就不行。这就是依赖反转!

tcp层需要知道http层的东西吗?ip层需要知道tcp层的东西吗?不需要!依赖反转原则应该作为大家在做架构设计时重要规则

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

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

相关文章

第11章 GUI Page417~418 步骤五 支持方框 使用宏定义

运行效果: 原来的创建item的方式: 使用宏定义的方式:

Java之LinkedList核心源码解读

LinkedList核心源码解读 LinkedList 是一个基于双向链表实现的集合类,经常被拿来和 ArrayList 做比较 LinkedList 插入和删除元素的时间复杂度? 头部插入/删除:只需要修改头结点的指针即可完成插入/删除操作,因此时间复杂度为 O…

PHP数组定义和输出

数组就是一组数据的集合,把一系列数据组织起来,形成一个可操作的整体。 PHP中的数组与Java的数组不一样,需要有key(键)和value(值),相当于Java中数组和键值对的结合。 数组的定义 …

redis 从0到1完整学习 (六):Hash 表数据结构

文章目录 1. 引言2. redis 源码下载3. dict 数据结构4. 哈希表扩容与 rehash5. 参考 1. 引言 前情提要: 《redis 从0到1完整学习 (一):安装&初识 redis》 《redis 从0到1完整学习 (二):red…

【Linux笔记】用户和权限管理基本命令介绍

🍎个人博客:个人主页 🏆个人专栏:Linux学习 ⛳️ 功不唐捐,玉汝于成 目录 ​编辑 前言: 命令: whoami: passwd: useradd: userdel: chm…

css 实现满屏升空的气球动画

最终实现效果 demo放在最后了。。。。 问题一 怎么实现满屏气球?简单理解就是多个气球的合并,难道要写多个盒子吗?确实是这样子,但可以有更好的办法,其实就是通过原生操作多个盒子生成,所以只需要实现一个…

智能优化算法应用:基于人工大猩猩部队算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于人工大猩猩部队算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于人工大猩猩部队算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工大猩猩部队算法4.实验参…

YZ系列工具之YZ03:高版本Excel的自定义菜单

我给VBA下的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套一部VBA手册,教程分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的…

关于游戏性能优化的技巧

关于游戏性能优化的技巧 游戏性能优化对象池Jobs、Burst、多线程间隔处理定时更新全局广播缓存组件缓存常用数据2D残影优化2D骨骼转GPU动画定时器优化DrawCall合批处理优化碰撞层优化粒子特效 游戏性能优化 好久没有在CSDN上面写文章了,今天突然看到鬼谷工作室技术…

docker部署mysql主主备份 haproxy代理(swarm)

docker部署mysql主主备份 haproxy代理(swarm) docker部署mysql主主备份 docker部署mysql主主备份(keepalived)跨主机自动切换 docker部署mysql主主备份 haproxy代理(swarm) 1. 环境准备 主机IPnode119…

WSL移动ubuntu到其他盘的几个问题以及安装,使用过程中遇到bug记录

这里写目录标题 无法正常修改Ubuntu系统的默认用户解决方案1:解决方案2: 出现 id xxx no such userGUI不能正常显示 无法正常修改Ubuntu系统的默认用户 ubuntu移动到其他盘可以参考WSL Ubuntu子系统迁移到非系统盘 下面问题是我安装时遇到的&#xff0c…

with torch.no_grad()在Pytorch中的应用

with torch.no_grad()在Pytorch中的应用 参考: https://blog.csdn.net/qq_24761287/article/details/129773333 https://blog.csdn.net/sazass/article/details/116668755 在学习Pytorch时,老遇到 with torch.no_grad(),搞不清其作用&#…

Linux内核模块文件组成介绍

Linux驱动开发主要的工作就是编写模块,一个典型的Linux内核模块文件.ko 主要由以下几个部分组成。 模块加载函数(必须) 当通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块的相关初始化工作。 Linux内核模…

MyBatis关联查询(二、一对多查询)

MyBatis关联查询(二、一对多查询) 需求:查询所有用户信息及用户关联的账户信息。 分析:用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,此时也要将用户信息查询出来&#xff0c…

竞赛保研 基于GRU的 电影评论情感分析 - python 深度学习 情感分类

文章目录 1 前言1.1 项目介绍 2 情感分类介绍3 数据集4 实现4.1 数据预处理4.2 构建网络4.3 训练模型4.4 模型评估4.5 模型预测 5 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于GRU的 电影评论情感分析 该项目较为新颖,适合作为竞…

msyql 24day 数据库主从 主从复制 读写分离 master slave 有数据如何增加

目录 环境介绍读写分离纵向扩展横向扩展 数据库主从准备环境主库环境(master)从库配置(slave)状态分析重新配置问题分析 报错解决从库验证 有数据的情况下 去做主从清理环境环境准备数据库中的锁的机制主库配置从库配置最后给主库解锁常见错误 环境介绍 将一个数据库的数据 复…

20Exchange第一轮空投延续铭文热-Meme热潮褪去后的选择

“凌晨1点打iotx铭文,凌晨2点打Tia铭文,凌晨3点打inj铭文,凌晨4点 打op铭文……”这个在社交网络上广为转发的贴文,浓缩了Web3用户对铭文市场的狂热。 从12月开始,铭文这种比特币等区块链网络铸造加密资产&#xff08…

从0到1部署gitlab自动打包部署项目

本文重点在于配置ci/cd打包 使用的是docker desktop 第一步安装docker desktop Docker简介 Docker 就像一个盒子,里面可以装很多物件,如果需要某些物件,可以直接将该盒子拿走,而不需要从该盒子中一件一件的取。Docker中文社区、…

零基础制作宠物用品小程序

随着人们对宠物用品的需求不断增长,越来越多的人开始探索如何制作一个专业的宠物用品小程序。而乔拓云作为一款功能强大的在线商城制作工具,成为了许多商家的首选。本文将详细介绍如何使用乔拓云制作宠物用品小程序,让你轻松上手,…

集合论:二元关系(1)

集合论这一章内容很多,重点是二元关系中关系矩阵,关系图和关系性质:自反、反自反、对称、反对称、传递以及关系闭包的运算,等价关系,偏序关系,哈斯图,真吓人! 1.笛卡儿积 由两个元素x和y按照一…