走向面向对象的六大原则--依赖倒置原则

面向对象编程的六大原则


让项目拥有变化的能力--依赖倒置原则
依赖倒置原则的英文全程是Dependence Inversion Principle,缩写是DIP,依赖倒置原则是一种特定的解耦形式,使得高层次的模块不依赖于低层次的模块的实现细节的目的,依赖模块被颠倒了。简单的说有以下几点:

  • 高层模块不应该依赖于底层模块,两者都应该依赖于其抽象。
  • 抽象不应该依赖于细节。
  • 细节应该依赖于抽象。

在Java语言中,抽象就是指接口和抽象类,两者都是不能直接被实例化的;细节就是指实现类,实现接口或继承抽象类而产生的类就是细节,细节可以被直接实例化。高层模块是指调用端,低层模块就是具体实现类。依赖倒置原则在Java中的表现就是:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或者抽象类产生的。

在我们之前的章节中,有一章的ImageLoader是依赖于具体实现的,代码如下:

public class ImageLoader {
    // 内存缓存(直接依赖于细节)
    MemoryCache mMemoryCache  = new MemoryCache ();
    // 线程池,线程数为CPU所允许的数量
    ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    //加载图片到ImageView中
    public void displayImg(final String url, final ImageView imageView) {
    }
    //从网络获取图片
    private Bitmap downloadImg(String imageUrl) {
    }

}

然后我们分析出该图片加载类只有内存缓存,已经无法满足我们的需求,于是我们设计出了DoubleCache类,此时便需要修改我们的代码:

public class ImageLoader {
    // 双缓存(直接依赖于细节)
    DoubleCache mDoubleCache   = new DoubleCache ();
    // 线程池,线程数为CPU所允许的数量
    ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    //加载图片到ImageView中
    public void displayImg(final String url, final ImageView imageView) {
    }
    //从网络获取图片
    private Bitmap downloadImg(String imageUrl) {
    }
}

我们将MemoryCache修改为DoubleCache,并且修改了部分缓存代码,就轻松地满足了我们的需求。但是!这里就违反了我们第二章所讲的开闭原则,这样设计出来的代码在后期需求改变时需要不停地修改,会使代码冗余并且容易出错。我们在开闭原则一章结束时的代码就很好地解决了这个问题,一句话概括起来就是:依赖抽象,而不依赖于具体实现。通过依赖注入的方式,可以保证系统的灵活性,我们回顾一下之前的代码(不熟悉的同学请回头阅读开闭原则:

ImageCache抽象类

public interface ImageCache {
    Bitmap get(String url);

    void put(String url,Bitmap bitmap);
}

ImageLoader类

 public class ImageLoader {
    // 图片缓存,依赖于抽象,并且有一个默认的实现
    ImageCache mImageCache = new MemoryCache();

    // 设置缓存策略,依赖于抽象
    public void setmImageCache(ImageCache cache){
        mImageCache = cache;
    }

    public void displayImage(String imageUrl,ImageView imageView){
    }
}

在这里,我们建立了ImageCache抽象,并且让ImageLoader依赖于抽象而不是具体细节。当我们的缓存策略发生改变时,我们只需要实现ImageCache或者集成已有的ImageCache子类完成具体的代码实现即可,这样就保证了我们的软件的高拓展性,有了变化的能力,这就是依赖倒置原则
从上述的几节我们也发现,好像要让系统变得灵活,抽象似乎成了我们唯一的手段。

推荐阅读更多精彩内容