后端技术面试38讲
李智慧
同程艺龙交通首席架构师,前Intel&阿里架构师,《大型网站技术架构》作者
立即订阅
3682 人已学习
课程目录
已更新 16 讲 / 共 38 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 掌握软件开发技术的第一性原理
免费
软件的基础原理 (8讲)
01丨程序运行原理:程序是如何运行又是如何崩溃的?
02丨数据结构原理:Hash表的时间复杂度为什么是O(1)?
03丨Java虚拟机原理:JVM为什么被称为机器(machine)?
04丨网络编程原理:一个字符的互联网之旅
05丨文件系统原理:如何用1分钟遍历一个100TB的文件?
06丨数据库原理:为什么PrepareStatement性能更好更安全?
07丨编程语言原理:面向对象编程是编程的终极形态吗?
答疑丨Java Web程序的运行时环境到底是怎样的?
软件的设计原理 (6讲)
08丨软件设计的方法论:软件为什么要建模?
09丨软件设计实践:如何使用UML完成一个设计文档?
10 | 软件设计的目的:糟糕的程序员比优秀的程序员差在哪里?
11丨软件设计的开闭原则:如何不修改代码却能实现需求变更?
12 | 软件设计的依赖倒置原则:如何不依赖代码却可以复用它的功能?
13丨软件设计的里氏替换原则:正方形可以继承长方形吗?
不定期加餐 (1讲)
加餐 | 软件设计文档示例模板
后端技术面试38讲
登录|注册

12 | 软件设计的依赖倒置原则:如何不依赖代码却可以复用它的功能?

李智慧 2019-12-18
在软件开发过程中,我们经常会使用各种编程框架。如果你使用的是 Java,那么你会比较熟悉 Spring、MyBatis 等。事实上,Tomcat、Jetty 这类 Web 容器也可以归类为框架。框架的一个特点是,当开发者使用框架开发一个应用程序时,无需在程序中调用框架的代码,就可以使用框架的功能特性。比如程序不需要调用 Spring 的代码,就可以使用 Spring 的依赖注入,MVC 这些特性,开发出低耦合、高内聚的应用代码。我们的程序更不需要调用 Tomcat 的代码,就可以监听 HTTP 协议端口,处理 HTTP 请求。
这些框架我们每天都在使用,已经司空见惯,所以觉得这种实现理所当然,但是我们停下好好想一想,难道不觉得这很神奇吗?我们自己也写代码,能够做到让其他工程师不调用我们的代码就可以使用我们的代码的功能特性吗?就我观察,大多数开发者是做不到的。那么 Spring、Tomcat 这些框架是如何做到的呢?

依赖倒置原则

我们看下 Spring、Tomcat 这些框架设计的核心关键点,也就是面向对象的基本设计原则之一:依赖倒置原则。
依赖倒置原则是这样的:
高层模块不应该依赖低层模块,二者都应该依赖抽象。
抽象不应该依赖具体实现,具体实现应该依赖抽象。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《后端技术面试38讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(16)

  • 山猫
    依赖倒置这个东西懂得人是真懂,不懂的人是一点不懂。当初为了搞懂依赖倒置原则花了相当长时间去阅读大量的文章和书籍,看了很多代码事例,后来又看了面对对象设计原则才算基本理解。

    之前给公司开发培训,他们仍旧听的一脸懵逼,觉得这是个噱头。直到我跟他们说:老板就是找个写代码的人,别把自己看的那么重。你们每天写那么多bug,别怪老板说要换人。他们才理解!

    作者回复: 这个解释精彩😁

    2019-12-18
    2
    7
  • 台风骆骆
    我觉得linux的vfs也是这种依赖倒置的,vfs定义一组通用的函数,如read,write,open,close,具体的文件系统实现这些接口,系统调用的时候去调用file结构中的f_op(对应具体的文件系统操作)。
    2019-12-18
    3
  • 唐二毛
    疑问: 按照我的理解,上层定义接口,对应到项目(传统三层架构),就是controller 层定义 service 层的接口,service层定义 dao层的接口,是这样吗? DI的目的是减少功能变化时,对代码的修改,可是我发现一旦这么做的时候,不但不能减少,反而会增加,因为功能的变化一般都是最上层的变化,比如: 参数的增加,减少,参数中字段的增加,减少,修改,这样的每一个变化都会影响到每一层的接口,所以在每一次功能变化的时候,都需要将整个调用链路的代码修改。 如果每层之间都加了防腐层,那每次变化都陷入到繁琐的改字段,测试字段之中。所有的unit test也要跟着变。这样真就是完完全全的牵一发而动全身! 有时我甚至觉得,把一个功能缩在一个类中,反而会更简单! 希望老师务必解答我的疑问,这个问题困扰我很久了!

    作者回复: 首先,依赖倒置后Service定义接口,DAO实现接口,不会导致变化更频繁,至少不会比原来DAO定义接口更频繁,因为从纯粹代码角度看,这个接口所有权的变化,换汤不换药,跟以前一样的。当然建议你用DDD的一些设计思路去设计服务和仓储,才能真正体现依赖倒置的优势,设计更稳定。

    其次,即使仅仅换汤不换药,也可以强迫设计者从Service的角度去设计接口,而不是从DAO角度设计接口,从而使接口的设计更加符合业务特点。

    2019-12-19
    1
  • Citizen Z
    老师可以具体阐述或举例说明下“策略层”、“方法层”、“工具层”的含义吗,是不是还有其他的层次名称的说法?
    2019-12-22
  • 你的美
    抽象就是可以用不同工具实现或定义多种不同方法的一种命令,有点绕
    2019-12-20
  • 靠人品去赢
    其实看很多框架的一些类的UML图,基本都是顶层是一个抽象的父类,然好一大堆接口引用。现在知道是依赖倒置思想作指导,但我有一个问题,想我们即使去使用抽象父类,来复用代码,虽然不会产生实例,但是怎么设计这个父类呢?有什么指导思想?比如我设计一个鸟类,比如会飞这个方法,有的特例企鹅就是不会飞,还有筑巢也是这样,怎么设计最好呢,还是压根不用父类?

    作者回复: 具体开发实践中,主要是用各种设计模式,而不是直接用设计原则去开发。设计模式也是基于设计原则的。

    2019-12-19
  • 俊伟
    网络协议里面的七层模型,不同的层之间就是基于抽象来建立的,上层不知道下层的存在,每层只需要专注当前层的逻辑
    2019-12-19
  • 隰有荷
    受益良多,晚上就要试试写一写代码,来增加对这一原则的理解。改一个代码就跟株代码九族一样,到处找,累死了
    2019-12-19
  • 一步
    按照文中的理解我们日常开发用的MVC是不符合依赖倒置的,若要满足依赖倒置就是的Control层抽象接口,Service层实现,Service层抽象接口DAO层去实现
    2019-12-18
    1
  • 一步
    高层模块和底层模块是依据什么划分的?

    作者回复: 根据调用关系,高层模块调用低层模块。即使是设计的时候依赖关系被倒置了,调用的时候也还是高层调用低层。

    2019-12-18
  • 夜空中最亮的星(华仔)
    受启发
    2019-12-18
  • 蓝魔丶
    请教老师一个问题,文中讲到我们平时使用的mvc开发模式是不满足依赖倒置原则的,因为不是高层定义接口抽象,但是即便是低层定义接口,只要不修改接口只修改实现,也是感觉没问题的,有必要强调这里的所属者吗?这个指导思想一般只是指导框架实践吧,平时编写代码好像都不会考虑这个
    2019-12-18
    1
  • 蓝魔丶
    隔壁设计模式介绍的模版方法以及观察者模式都算依赖倒置
    2019-12-18
  • 探索无止境
    如果再加上一段对tomcat或框架源码的对应解读就完美了
    2019-12-18
  • 丁丁历险记
    意图层被高层占用,更好的实现了意图和实现分离。
    最基础的factory 实现的就是dip 原则
    2019-12-18
  • 盖瑞Chen
    好像生活中也有依赖倒置的例子,比如开车,你不依赖我,我也不依赖你,共同依赖交通法规。不知道这样理解对不对
    2019-12-18
    1
收起评论
16
返回
顶部