这本《设计模式之禅》得来不易,当时是在CSDN的论坛中向秦小波老师提问有幸获得的。读这种经典书籍不能如读小说,逛十里洋场意在消遣,更多的应该是边读变问,每到重点就应该问为什么。秦小波老师的语言有时幽默,有时又切中要害,引人深思。对于“倒置”秦小波老师是从人的思维层面解读的,生活中,例如张三就依赖他家的宝马上下班,也许可以更具体到BMW 740Li,然后回归到程序中,如果我们这样去构建依赖关系,那么如果哪天张三发达了,换了玛莎拉蒂,那是不是整个程序都得改,这个时候我们可以让张三依赖的对象变成接口或者抽象类,例如是“车”,那么张三如果换了玛莎拉蒂,可以增加一个“玛莎拉蒂”的车的实现。当依赖不在是具体而是抽象,这种思维的转变就称之为倒置。
在该书的第23页的代码清单3-8中你会看到
代码一
public static void main(String[] args) { // TODO Auto-generated method stub /*Driver jim=new Driver(); BMW bmw =new BMW();*/ IDriver jim = new Driver(); ICar bmw =new BMW(); jim.drive(bmw); }我以前都是采用的注释中的写法,但秦小波老师的书中却是没有注释的写法,对于这个问题思考良久后才明白注释中的写法中的jim对象不仅拥有接口中的方法,而且还拥有Driver类的方法,但是没有注释的写法中的jim对象就只拥有接口中的方法。例如如果Driver类还有一个修车的方法,那么采用秦老师的new一个对象,该对象就不能调用修车的方法。代码如下:
代码二
public class Driver implements IDriver{ @Override public void drive(ICar car) { // TODO Auto-generated method stub car.run(); } public void fix() { System.out.println("I can fix my car"); } }
代码三
public class Driver implements IDriver{ private ICar car; public Driver(ICar _car) { this.car=_car; } public void drive() { this.car.run(); } }从代码三看出增加了构造方法,通过构造方法传递依赖的ICar对象,这样在IDriver接口中的drive方法就不需要任何参数了,如果以后ICar发生了变化,只需要改Driver的构造方法即可,其余代码均不需要修改。
总结
依赖倒置原则可以说是六大设计原则中比较难理解的,在很多框架中都用到该原则,例如Spring。程序世界和现实世界一样是普遍联系的,换句话说就是对象也是存在依赖关系的,我们不可能让所有的对象都割裂开来,那这样的话程序也没法运转,在保持依赖的同时需要降低对象之间的耦合度,能真正做好确实是一门艺术,就如代码二和代码三是不同的做法,最终都能输出同样的结果,并且代码三比代码二还要复杂,但是如果考虑以后程序的扩展,显然代码三优于代码二。关于倒置,我想秦小波老师是说得最朴实的,让我们从简单的语言中深刻体会倒置的思想。
读秦小波老师《设计模式之禅》问一-依赖倒置原则,布布扣,bubuko.com
原文地址:http://blog.csdn.net/dotnetstudio/article/details/38492385