首页 新闻 搜索 专区 学院

依赖倒置原则的“倒置”体现在哪里,”依赖倒置“为什么不叫”依赖转移“而叫”倒置“(高人勿入)

0
悬赏园豆:50 [已解决问题] 解决于 2015-05-29 12:08

问题太二,请高人勿入,以免影响双方的心情


将传统的设计方式——高层类依赖低层类,修改为高层类依赖于对底层类的抽象,低层类也依赖于抽象。以上是我理解的依赖倒置原则。到底“倒置”体现在哪里呢?

帖一个OODesign上的例子:

传统的设计:

// Dependency Inversion Principle - Bad example

class Worker {

    public void work() {

        // ....working

    }

}



class Manager {

    Worker worker;



    public void setWorker(Worker w) {
        worker = w;
    }

    public void manage() {
        worker.work();
    }
}

class SuperWorker {
    public void work() {
        //.... working much more
    }
}

优化后的设计:

// Dependency Inversion Principle - Good example
interface IWorker {
    public void work();
}

class Worker implements IWorker{
    public void work() {
        // ....working
    }
}

class SuperWorker  implements IWorker{
    public void work() {
        //.... working much more
    }
}

class Manager {
    IWorker worker;

    public void setWorker(IWorker w) {
        worker = w;
    }

    public void manage() {
        worker.work();
    }
}

上面的例子中,将高层对低层的依赖修改为了高层对抽象层的依赖,这样为什么就称之为“倒置”了,谁和谁倒了?如果A依赖于B,那么改成B依赖于A,这可以叫倒置;A依赖于B,改成了A依赖于C,B依赖于C为什么就叫”倒置“啊,我觉得应该叫”依赖转移“呀。

 

是不是可以这样理解:高层A依赖于低层B修改为高层A依赖于抽象层C,低层B依赖于抽象层C,而抽象层C是低层B的高层,所以说低层依赖于高层了,即倒置。但是A依赖于C,这个不能说是低层依赖于高层吧,A和C谁高谁低是这么判定的?

 

再补充一个《设计模式之禅》中对”倒置“的解释:


”讲了这么多,估计大家对“倒置”这个词还是有点不理解,那到底什么是“倒置”呢?我们先说“正置”是什么意思,依赖正置就是类间的依赖是实实在在的实现类间的依赖,也就是面向实现编程,这也是正常人的思维方式,我要开奔驰车就依赖奔驰车,我要使用笔记本电脑就直接依赖笔记本电脑,而编写程序需要的是对现实世界的事物进行抽象,抽象的结果就是有了抽象类和接口,然后我们根据系统设计的需要产生了抽象间的依赖,代替了人们传统思维中的事物间的依赖,“倒置”就是从这里产生“。

 

概括一下就是说“具体间的依赖转变为了抽象间的依赖,'倒置'就这样产生“,好像没有解释为什么叫”倒置“啊。


附:OODesign对依赖倒置的解释:http://www.oodesign.com/dependency-inversion-principle.html

”倒“字的意思:

 1. 位置上下前后翻转:~立。~挂。~影。~置。

 2. 把容器反转或倾斜使里面的东西出来:~水。~茶。

 3. 反过来,相反地:~行逆施。反攻~算。~贴。

 4. 向后,往后退:~退。~车。

 5. 却:东西~不坏,就是旧了点。

inversion的翻译:

倒置; 转化; (尤指词序)倒装; (染色体的)倒位; 

会长的主页 会长 | 专家六级 | 园豆:10922
提问于:2015-05-28 23:30
< >
分享
最佳答案
0

倒置的是顺序,不是对象。

原来,你要先有A,才能有B,

现在你可以先有B,啥时候高兴了,再编A。

收获园豆:50
爱编程的大叔 | 高人七级 |园豆:30768 | 2015-05-29 09:35

言之有理!

会长 | 园豆:10922 (专家六级) | 2015-05-29 09:58

不仅仅是A和B的问题,最主要的是要进行抽象。

之前是A依赖于B。

改进之后是A依赖于C。但是C和B之间是有继承关系。

C是对B进行了抽象处理,而且之后A里面可以使用的不仅仅是B,还有可能是从C派生出来的其他类

 

ChuckLu | 园豆:514 (小虾三级) | 2015-06-01 19:02

@ChuckLu: 这我知道,我只是想知道为什么叫“倒置”,谁和谁倒了

会长 | 园豆:10922 (专家六级) | 2016-03-27 22:38

@会长: 问的很好 这些技术大拿就喜欢瞎比起名 来迷惑我们 要不怎么显得高大上!

eagle_wolf | 园豆:144 (初学一级) | 2017-03-29 10:44
其他回答(8)
1

理解“依赖倒置”,要参考 OOP 的核心思想:一切皆对象。这里的“倒置”,是指存有依赖关系的双方,依赖关系的倒置。双方都是对象,而不是你所理解的三个Class(或Interface)的关系转变。

另外,你写这个例子好像不太合适,我印象中第一个例子里不能有setWorker方法。Worker对象是在Manager里New的。参见百度百科:

http://baike.baidu.com/link?url=_bDzNL05KIN_6NxBzzd0p0ivDMLilVCVvlEpMzrsQpN-Dn7WkGTsnEKLSh6SxPe8Ha2xJYTxJvJl5v66XF2-ta

小浩叔叔 | 园豆:210 (菜鸟二级) | 2015-05-29 05:29

这可是权威网站 www.oodesign.com的例子啊。依赖关系如何看出来是倒置了。如果A依赖于B变成B依赖于A才算倒置,您能指明A和B是分别是什么吗,您说的“依赖关系的双方”是哪双方,谢谢。如阁下有时间的话可否举个例子展示下“依赖关系的双方”,如果没时间的话就算了,请继续参与讨论并关注该问题,谢谢。

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2015-05-29 08:57

这个网站应该是比较权威的,因为《设计模式之禅》就参考这个网站了,而且里面的“单一职责原则”中的代码例子和人家网站里的几乎一样。

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2015-05-29 09:02

@会长: 是我理解太局限了。。我站在了对象的层面,而没有提升到抽象的层面。。你参考“爱编程的大叔”的就行了。。不好意思

支持(0) 反对(0) 小浩叔叔 | 园豆:210 (菜鸟二级) | 2015-05-29 13:53

@张浩华: 谢谢,请原谅我太较真

支持(2) 反对(0) 会长 | 园豆:10922 (专家六级) | 2016-03-17 21:48
0

个人理解 就是面向接口编程。

whlalhj | 园豆:229 (菜鸟二级) | 2015-05-29 11:20

 雷子,我想问的是为什么叫“倒置”。

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2015-05-29 12:08
3

是不是可以这样理解:高层A依赖于低层B修改为高层A依赖于抽象层C,低层B依赖于抽象层C,而抽象层C是低层B的高层,所以说低层依赖于高层了,即倒置。但是A依赖于C,这个不能说是低层依赖于高层吧,A和C谁高谁低是这么判定的?

-----------------------------------------------

因为抽象层C是属于A层的,即由A层来规定抽象层C的接口规范,而B是对C的实现,因此通过引入C层实现了“依赖倒置”

潇湘雨歇 | 园豆:207 (菜鸟二级) | 2015-05-29 14:44

有道理,现在博客园结贴后也能答题了?可惜不能给你分了

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2015-05-29 19:42
0

你可以看看这个,讲的不错的

http://www.cnblogs.com/cbf4life/archive/2009/12/15/1624435.html

ChuckLu | 园豆:514 (小虾三级) | 2015-06-01 18:32

谢谢,他的书我也在看。

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2015-06-01 23:07
0

 "倒置"不是指依赖顺序 而是指思考上的顺序是倒的 :比如你想开一个咖啡店,首先考虑的是咖啡店的地址,装潢,要雇几个店员,买什么样的设备 ,最后才是做什么样的咖啡(摩卡,拿铁,卡布奇诺什么的...),顺序是从整体到具体;而所谓的"倒置"就是反过来,先考虑要做什么样的咖啡,然后抽象出所需要的方法,最后考虑顶层实现.

这样就从A(咖啡店)->B(咖啡) 变成了 B(咖啡)->AB(咖啡的抽象)->A(咖啡店).

所谓的倒置就是这这个顺序

jeolo | 园豆:202 (菜鸟二级) | 2016-12-14 17:34

 你说的对,我也理解了,谢谢。

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2017-01-16 11:15

这个回复妙啊!AB的合体被依赖了,AB被看成一个整体了才真正体现出了"倒置"的概念

支持(0) 反对(0) 谁抢我名字 | 园豆:202 (菜鸟二级) | 2020-09-30 16:10
0

https://www.jianshu.com/p/8d7723cd4e24 这篇文章写的不错,可以看看

想54256 | 园豆:194 (初学一级) | 2020-03-03 11:23

我已经理解了。谢谢你。

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2020-03-03 11:28
0

感谢博主的问贴,搞懂了!!这里再此总结一下我的想法,方便后面的人阅读。
通常情况下A类调用(依赖)B类,你需要先定义B类,随后才能定义A类,现在引入了C接口,你可以先写好A类和C类,然后再写B类。所以这里的先后顺序发生了变化(先A再B到先B再A),故称之为依赖倒置。

小葱111 | 园豆:202 (菜鸟二级) | 2020-03-30 14:57

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2020-03-30 18:22
1

百度百科这个讲的挺好的,我一下就懂怎么运行了,但是真心不觉得倒置了什么东西,只是加了一个中间层,
面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变动时上层也要跟着变动,这就会导致模块的复用性降低而且大大提高了开发的成本。
面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。
https://baike.baidu.com/item/依赖倒置原则/6189149?fr=aladdin

耕耘者1294480 | 园豆:202 (菜鸟二级) | 2021-01-31 11:33

谢谢回复。这个问题估计是博客园活的最久的问题之一了

支持(0) 反对(0) 会长 | 园豆:10922 (专家六级) | 2021-02-01 11:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册