设计模式之美
王争
前Google工程师,《数据结构与算法之美》专栏作者
立即订阅
17765 人已学习
课程目录
已更新 23 讲 / 共 100 讲
0/6登录后,你可以任选6讲全文学习。
开篇词 (1讲)
开篇词 | 一对一的设计与编码集训,让你告别没有成长的烂代码!
免费
设计模式学习导读 (3讲)
01 | 为什么说每个程序员都要尽早地学习并掌握设计模式相关知识?
02 | 从哪些维度评判代码质量的好坏?如何具备写出高质量代码的能力?
03 | 面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
设计原则与思想:面向对象 (11讲)
04 | 理论一:当谈论面向对象的时候,我们到底在谈论什么?
05 | 理论二:封装、抽象、继承、多态分别可以解决哪些编程问题?
06 | 理论三:面向对象相比面向过程有哪些优势?面向过程真的过时了吗?
07 | 理论四:哪些代码设计看似是面向对象,实际是面向过程的?
08 | 理论五:接口vs抽象类的区别?如何用普通的类模拟抽象类和接口?
09 | 理论六:为什么基于接口而非实现编程?有必要为每个类都定义接口吗?
10 | 理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?
11 | 实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?
12 | 实战一(下):如何利用基于充血模型的DDD开发一个虚拟钱包系统?
13 | 实战二(上):如何对接口鉴权这样一个功能开发做面向对象分析?
14 | 实战二(下):如何利用面向对象设计和编程开发接口鉴权功能?
设计原则与思想:设计原则 (6讲)
15 | 理论一:对于单一职责原则,如何判定某个类的职责是否够“单一”?
16 | 理论二:如何做到“对扩展开放、修改关闭”?扩展和修改各指什么?
17 | 理论三:里式替换(LSP)跟多态有何区别?哪些代码违背了LSP?
18 | 理论四:接口隔离原则有哪三种应用?原则中的“接口”该如何理解?
19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?
20 | 理论六:我为何说KISS、YAGNI原则看似简单,却经常被用错?
不定期加餐 (2讲)
加餐一 | 用一篇文章带你了解专栏中用到的所有Java语法
加餐二 | 设计模式、重构、编程规范等相关书籍推荐
设计模式之美
登录|注册

19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?

王争 2019-12-16
关于 SOLID 原则,我们已经学过单一职责、开闭、里式替换、接口隔离这四个原则。今天,我们再来学习最后一个原则:依赖反转原则。在前面几节课中,我们讲到,单一职责原则和开闭原则的原理比较简单,但是,想要在实践中用好却比较难。而今天我们要讲到的依赖反转原则正好相反。这个原则用起来比较简单,但概念理解起来比较难。比如,下面这几个问题,你看看能否清晰地回答出来:
“依赖反转”这个概念指的是“谁跟谁”的“什么依赖”被反转了?“反转”两个字该如何理解?
我们还经常听到另外两个概念:“控制反转”和“依赖注入”。这两个概念跟“依赖反转”有什么区别和联系呢?它们说的是同一个事情吗?
如果你熟悉 Java 语言,那 Spring 框架中的 IOC 跟这些概念又有什么关系呢?
看了刚刚这些问题,你是不是有点懵?别担心,今天我会带你将这些问题彻底搞个清楚。之后再有人问你,你就能轻松应对。话不多说,现在就让我们带着这些问题,正式开始今天的学习吧!

控制反转(IOC)

在讲“依赖反转原则”之前,我们先讲一讲“控制反转”。控制反转的英文翻译是 Inversion Of Control,缩写为 IOC。此处我要强调一下,如果你是 Java 工程师的话,暂时别把这个“IOC”跟 Spring 框架的 IOC 联系在一起。关于 Spring 的 IOC,我们待会儿还会讲到。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《设计模式之美》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(61)

  • 小晏子
    课后思考:
    “基于接口而非实现编程”与“依赖注入”的联系是二者都是从外部传入依赖对象而不是在内部去new一个出来。
    区别是“基于接口而非实现编程”强调的是“接口”,强调依赖的对象是接口,而不是具体的实现类;而“依赖注入”不强调这个,类或接口都可以,只要是从外部传入不是在内部new出来都可以称为依赖注入。
    2019-12-16
    29
  • 下雨天
    区别:
    1.依赖注入是一种具体编程技巧,关注的是对象创建和类之间关系,目的提高了代码的扩展性,我们可以灵活地替换依赖的类。
    2.基于接口而非实现编程是一种设计原则,关注抽象和实现,上下游调用稳定性,目的是降低耦合性,提高扩展性。

    联系:
    都是基于开闭原则思路,提高代码扩展性!
    2019-12-16
    16
  • 辣么大
    1⃣️控制反转是一种编程思想,把控制权交给第三方。依赖注入是实现控制反转最典型的方法。
    2⃣️依赖注入(对象)的方式要采用“基于接口而非实现编程”的原则,说白了就是依赖倒转。
    3⃣️低层的实现要符合里氏替换原则。子类的可替换性,使得父类模块或依赖于抽象的高层模块无需修改,实现程序的可扩展性。
    2019-12-16
    9
  • 业余爱好者
    原来的模式是一个spring开发的项目放在Tomcat中,控制权在Tomcat手中。现在微服务兴起,大家都用springboot开发。此时是Tomcat在springboot项目当中。控制权在springboot手中,虽然只是表面上。这便是控制反转。

    这是一场控制权争夺之战。
    2019-12-16
    3
    9
  • KIM
    感觉比head first设计模式讲的清晰
    2019-12-16
    5
  • Ken张云忠
    区别:
    基于接口而非实现编程:是面向对象编程的一种方式.减少对外部的依赖,还可以提升代码的灵活性,扩展及修改时可以控制风险的传播,符合开闭原则.
    依赖注入:是一种具体的编码技巧,属于编程规范的范畴.不通过 new 的方式在类内部创建依赖类的对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类来使用。
    联系:
    两者结合在一起可以实现代码的灵活性,减少对外部的依赖,提升代码的可维护性/可扩展性.
    课外感想:
    非常喜欢王争老师这样有深度内涵的课程,概念理解深入透彻,宏观方向把握准确,跟着老师的课程更有信心去挑战阿里这样一流企业的工作.报告老师,我归队了.
    2019-12-16
    4
  • MindController
    深夜打卡
    2019-12-16
    1
    4
  • 帆大肚子
    在我看来,“依赖注入”是“基于接口而非实现编程”的一个实践。
    “基于接口而非实现编程”是一条设计原则,可以帮助我们诞生更多类似于“依赖注入”的实践
    2019-12-16
    2
  • iLeGeND
    有收获
    2019-12-16
    2
  • 阿冰777
    基于接口而非实现编程(依赖倒置原则): 高层和低层组件都使用了一样的接口,然后让接口去控制整个逻辑,这样高层组件就不会依赖于具体的低层组件实现。简单来讲,就是大家都用接口,彼此不认识。
    依赖注入:依赖注入就是一个组件内部依赖一个对象,但是他不自己造,等别人送上来。
    他们俩的关系就是,在依赖倒置原则指导下的设计里,组件都没有内部创造依赖的对象,全是通过外部传入的,但是也不一定是注入,有可能只是个过客(传进去用完就扔),而且注入的时候,都是以接口的形式注入的,而依赖注入并不一定是接口。
    2019-12-16
    1
  • 再见孙悟空
    “基于接口而非实现编程” 和 “依赖注入”

    联系 :
    都能实现注入功能,程序依赖的对象都能在外部事先创建而无需程序内部显示 new 。

    区别:
    “基于接口而非实现编程” 可以看作是 “依赖注入” 的一种实现方式。除了构造方法注入外,依赖注入还包括 setter 方法注入。
    2019-12-16
    1
  • 空知
    Ioc样例代码那里,抽象类TestCase 的doTest方法 应该返回布鲁尔值,而不是void
    2019-12-16
    1
  • 睡觉💤
    控制反转:控制指的是程序流程的控制,反转是指程序的流程的控制权由程序员转移到框架
    依赖注入:上层类依赖底层类执行业务,以前往往将底层类作为上层类的成员变量,在上层类的内部声明底层类。注入就是底层类在外边声明,通过接口的方式注入到上层类中
    依赖反转原则:我的理解是模块的解耦。上层模块依赖于低等模块,通过抽象出一套规则或者接口,使得上层业务依赖于抽象规则,低层业务实现规则。

    我觉得基于接口编程与依赖反转原则比较类似,区别的话,依赖反转原则,依赖的不一定非得是接口,也许是一套规则,比如老师举的tomcat与java服务的例子
    2019-12-16
    1
  • 李小四
    设计模式_19
    # 作业
    “基于接口而非实现编程”: 是一种设计原则。
    “依赖注入”: 一种对上面原则的应用。

    # 感想:
    今天的内容,一定程度上是对前面基础原则的组合式实践。
    在依赖反转原则里,
    “具体实现依赖抽象”,是对“基于接口而非实现编程”的实践。
    比如“高层模块不要依赖低层模块”,是“开闭原则”的实践。

    像“单一职责”、“开闭原则”等的底层原则,我们都能理解它的“字面含义”,但真正掌握它要更多的实践和更丰富的信息量,这是我理解的,为什么还要继续讲基于基础原则的实践。
    2019-12-16
    1
  • Smallfly
    依赖倒置原则概念是高层次模块不依赖于低层次模块。看似在要求高层次模块,实际上是在规范低层次模块的设计。

    低层次模块提供的接口要足够的抽象、通用,在设计时需要考虑高层次模块的使用种类和场景。

    明明是高层次模块要使用低层次模块,对低层次模块有依赖性。现在反而低层次模块需要根据高层次模块来设计,出现了「倒置」的显现。

    这样设计好处有两点:

    1. 低层次模块更加通用,适用性更广
    2. 高层次模块没有依赖低层次模块的具体实现,方便低层次模块的替换

    思考题:

    基于接口而非实现编程,是一种指导编码的思想。依赖注入是它的一种具体应用。

    个人理解,仅供参考~
    2019-12-16
    1
    1
  • 墨雨
    感觉依赖反转原则是不是可以叫“依赖抽象原则”?😂,从字面意思来看我觉得可以翻译成:高层模块和低层模块及实现细节都应依赖于抽象。
    2019-12-16
    1
  • MarksGui
    这个专栏确实讲解的非常细致!争哥确实是用心做专栏!以前对很多类似的概念都没理解透彻,通过这个专栏完全明白了!
    2019-12-16
    1
  • 秋天
    区别就是依赖注入属于框架层面,接口编程属于实现层面
    2019-12-16
    1
  • Paul Shan
    控制反转的本质是分拆控制代码和具体执行代码,控制代码放在较高的层次上,也可能交给第三方类库,实现代码放在较低的层次上,通常是一个接口的实现。

    依赖反转本质是分拆类中的new语句,因为new语句引入了对实现类构造函数的依赖,属于很强的依赖。分拆之后构造和实现放在另外一个类里(通常交给第三方类库),使用的地方引用接口。依赖反转可以拆分类的依赖关系,可以减少实现类的引用,用接口取代,实现接口和实现的分离。依赖反转和基于接口而非实现的原则类似,两者都倾向于依赖接口而非具体类。不同点在于,前者更关注类层次中的依赖关系以及对构造函数的依赖,尽量避免高层次的类依赖底层的实现,尽量避免对构造函数的依赖。后者,更强调类的使用的地方,尽量使用更抽象更宽泛的接口,而非更具体更细节的实现,使得信息隐藏和抽象。

    控制反转和依赖反转都是有成本的,会破坏代码的内聚性和简洁性,需要权衡使用。
    2019-12-16
    1
  • javaadu
    课堂讨论:这两个概念没什么关系,讲的不是一个事。依赖注入讲的是一个对象如何获得它运行所依赖的对象,所谓依赖注入就是不需要自己去new,让框架注入进来;基于接口而不是实现编程讲的是抽象思维的应用,利用编程,可以屏蔽掉底层具体实现改变导致上层改变的问题。

    文中的那个例子,只是恰好同时使用了依赖注入这个编程技巧,同时也实践了基于接口而非实现编程这个原则。
    2019-12-17
收起评论
61
返回
顶部