问题太二,请高人勿入,以免影响双方的心情
将传统的设计方式——高层类依赖低层类,修改为高层类依赖于对底层类的抽象,低层类也依赖于抽象。以上是我理解的依赖倒置原则。到底“倒置”体现在哪里呢?
帖一个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的翻译:
倒置; 转化; (尤指词序)倒装; (染色体的)倒位;
倒置的是顺序,不是对象。
原来,你要先有A,才能有B,
现在你可以先有B,啥时候高兴了,再编A。
言之有理!
不仅仅是A和B的问题,最主要的是要进行抽象。
之前是A依赖于B。
改进之后是A依赖于C。但是C和B之间是有继承关系。
C是对B进行了抽象处理,而且之后A里面可以使用的不仅仅是B,还有可能是从C派生出来的其他类
@ChuckLu: 这我知道,我只是想知道为什么叫“倒置”,谁和谁倒了
@会长: 问的很好 这些技术大拿就喜欢瞎比起名 来迷惑我们 要不怎么显得高大上!
理解“依赖倒置”,要参考 OOP 的核心思想:一切皆对象。这里的“倒置”,是指存有依赖关系的双方,依赖关系的倒置。双方都是对象,而不是你所理解的三个Class(或Interface)的关系转变。
另外,你写这个例子好像不太合适,我印象中第一个例子里不能有setWorker方法。Worker对象是在Manager里New的。参见百度百科:
http://baike.baidu.com/link?url=_bDzNL05KIN_6NxBzzd0p0ivDMLilVCVvlEpMzrsQpN-Dn7WkGTsnEKLSh6SxPe8Ha2xJYTxJvJl5v66XF2-ta
这可是权威网站 www.oodesign.com的例子啊。依赖关系如何看出来是倒置了。如果A依赖于B变成B依赖于A才算倒置,您能指明A和B是分别是什么吗,您说的“依赖关系的双方”是哪双方,谢谢。如阁下有时间的话可否举个例子展示下“依赖关系的双方”,如果没时间的话就算了,请继续参与讨论并关注该问题,谢谢。
这个网站应该是比较权威的,因为《设计模式之禅》就参考这个网站了,而且里面的“单一职责原则”中的代码例子和人家网站里的几乎一样。
@会长: 是我理解太局限了。。我站在了对象的层面,而没有提升到抽象的层面。。你参考“爱编程的大叔”的就行了。。不好意思
@张浩华: 谢谢,请原谅我太较真
个人理解 就是面向接口编程。
雷子,我想问的是为什么叫“倒置”。
是不是可以这样理解:高层A依赖于低层B修改为高层A依赖于抽象层C,低层B依赖于抽象层C,而抽象层C是低层B的高层,所以说低层依赖于高层了,即倒置。但是A依赖于C,这个不能说是低层依赖于高层吧,A和C谁高谁低是这么判定的?
-----------------------------------------------
因为抽象层C是属于A层的,即由A层来规定抽象层C的接口规范,而B是对C的实现,因此通过引入C层实现了“依赖倒置”
有道理,现在博客园结贴后也能答题了?可惜不能给你分了
你可以看看这个,讲的不错的
http://www.cnblogs.com/cbf4life/archive/2009/12/15/1624435.html
谢谢,他的书我也在看。
"倒置"不是指依赖顺序 而是指思考上的顺序是倒的 :比如你想开一个咖啡店,首先考虑的是咖啡店的地址,装潢,要雇几个店员,买什么样的设备 ,最后才是做什么样的咖啡(摩卡,拿铁,卡布奇诺什么的...),顺序是从整体到具体;而所谓的"倒置"就是反过来,先考虑要做什么样的咖啡,然后抽象出所需要的方法,最后考虑顶层实现.
这样就从A(咖啡店)->B(咖啡) 变成了 B(咖啡)->AB(咖啡的抽象)->A(咖啡店).
所谓的倒置就是这这个顺序
你说的对,我也理解了,谢谢。
这个回复妙啊!AB的合体被依赖了,AB被看成一个整体了才真正体现出了"倒置"的概念
感谢博主的问贴,搞懂了!!这里再此总结一下我的想法,方便后面的人阅读。
通常情况下A类调用(依赖)B类,你需要先定义B类,随后才能定义A类,现在引入了C接口,你可以先写好A类和C类,然后再写B类。所以这里的先后顺序发生了变化(先A再B到先B再A),故称之为依赖倒置。
赞
百度百科这个讲的挺好的,我一下就懂怎么运行了,但是真心不觉得倒置了什么东西,只是加了一个中间层,
面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变动时上层也要跟着变动,这就会导致模块的复用性降低而且大大提高了开发的成本。
面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。
https://baike.baidu.com/item/依赖倒置原则/6189149?fr=aladdin
谢谢回复。这个问题估计是博客园活的最久的问题之一了