依赖倒置原则指代了一种特定的解耦形式,使得高层次的模块不依赖于低层次的模块的实现细节的目的,而是依赖于抽象。这里的抽象就是指接口或抽象类,不能被实例化的。依赖倒置原则有3个关键点:
1、高层模块不应该依赖底层模块,两者都应该依赖其抽象。
2、抽象不应该依赖其细节。
3、细节应该依赖于抽象。
这里的细节就是指实现类,实现接口或者继承抽象类而产生的类就是细节,其特点就是,可以直接实例化。高层模块就是调用端,底层模块就是具体实现类。依赖倒置原则的表现就是:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系。依赖关系通过接口或者抽象类产生。其实一句话,就是面向抽象编程,面向抽象编程是面向对象编程的精髓之一。
如果类于类之间依赖于细节,那么她们之间就有直接的耦合,当具体实现需要变化时,必须要同时修改依赖者的代码,这限制了系统的可扩展性。
回顾代码:
package com.example.yangshin99.myapplication;
import android.graphics.Bitmap;
/**
* Created by yangshin99 on 16/2/15.
*/
public interface ImageCache {
public Bitmap get(String url);
public void put(String url,Bitmap bmp);
}
package com.example.yangshin99.myapplication;
import android.graphics.Bitmap;
import android.util.LruCache;
/**
* Created by yangshin99 on 16/2/15.
*/
public class MemoryCache implements ImageCache {
private LruCache<String,Bitmap> mMemeryCache;
public MemoryCache(){
//初始化缓存
}
@Override
public Bitmap get(String url) {
return mMemeryCache.get(url);
}
@Override
public void put(String url, Bitmap bmp) {
mMemeryCache.put(url,bmp);
}
}
/**
* Created by yangshin99 on 16/2/12.
* 图片加载类,
*/
public class ImageLoader {
//图片缓存
ImageCache mImageCache = new MemoryCache();
//是否使用SD卡缓存
boolean isUseDiskCache = false;
//使用双缓存
boolean isUseDoubleCache = false;
//线程池,线程数量为CPU的数量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
//注入缓存实现
public void setImageCache(ImageCache cache){
mImageCache = cache;
}
public void displayImage(final String url, final ImageView imageView){
Bitmap bitmap = mImageCache.get(url);
if (bitmap != null){
imageView.setImageBitmap(bitmap);
return;
}
//图片没有缓存,提交线程池下载.
submitLoadRequest(url, imageView);
}
在上面代码,我们建立了ImageCache抽象,并且让ImageLoader依赖于抽象而不是具体细节,当需求发生变化时,只需要实现ImageCache子类完成相应的缓存功能,然后将具体的实现注入到 ImageLoader即可实现缓存功能的替换,这就保证了缓存系统的高扩展性,有了拥抱变化的能力,这就是依赖倒置原则,依赖于抽象,而不依赖于细节。让系统更为灵活,抽象是重要的手段。