《设计模式之禅》依赖倒置原则之问

最近在看秦小波老师的《设计模式之禅》,读这种经典书籍不能如读小说,逛十里洋场意在消遣,更多的应该是边读变问,每到重点就应该问为什么。秦小波老师的语言有时幽默,有时又切中要害,引人深思。对于“倒置”秦小波老师是从人的思维层面解读的,生活中,例如张三就依赖他家的宝马上下班,也许可以更具体到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");
    }
}

在该书的25页采用了构造函数传递依赖对象,秦老师没有说明为什么要这样做。从代码二中看到,直接将ICar作为一个参数传进来的,这样的话,不仅接口IDriver的drive方法需要有这个参数,以后任意一个实现该接口的类都必须这样做,这无疑增加了程序的耦合度。先看看下面的代码吧。

代码三

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。程序世界和现实世界一样是普遍联系的,换句话说就是对象也是存在依赖关系的,我们不可能让所有的对象都割裂开来,那这样的话程序也没法运转,在保持依赖的同时需要降低对象之间的耦合度,能真正做好确实是一门艺术,就如代码二和代码三是不同的做法,最终都能输出同样的结果,并且代码三比代码二还要复杂,但是如果考虑以后程序的扩展,显然代码三优于代码二。关于倒置,我想秦小波老师是说得最朴实的,让我们从简单的语言中深刻体会倒置的思想。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值