依赖倒转原则
依赖倒转原则也称为依赖倒置原则。
依赖倒转原则:
- 高层模块不应该依赖低层模块,两个都应该依赖抽象。
- 抽象不应该依赖细节。细节应该依赖抽象。
- 针对接口编程,不要针对实现编程。
在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化,也就是可以加上一个关键字 new 产生一个对象。
高层模块就是调用端,低层模块就是具体实现类。依赖倒转原则在Java语言中的表现是:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
为什么要叫倒转呢?
面向过程的开发时,为了使得常用代码可以复用,一般都会把这些常用代码写成许许多多函数的程序库,这样我们在做新项目时,去调用这些低层的函数就可以了。比如我们做的项目大多要访问数据库,所以我们就把访问数据库的代码写成了函数,每次做新项目时就去调用这些函数。这也就叫做高层模块依赖低层模块。
如果类于类直接依赖于细节,那么它们之间就有直接的耦合,当具体需要变化时,要同时修改依赖者的代码,这就限制了系统的可扩展性。如:ImageLoader 直接依赖于 MemoryCache,这个 MemoryCache 是一个具体实现,而不是一个抽象类或者接口。这就导致了 ImageLoader 直接依赖了具体细节,当 MemoryCache 不能满足 ImageLoader 而需要被其他缓存实现替换时,此时就 必须修改 ImageLoader 的代码,例如:
public class ImageLoader{
//内存缓存(直接依赖于细节)
MemoryCache mMemoryCache = new MemoryCache();
//加载图片到ImageView中
public void displayImage(String url, ImageView imageView){
}
}
随着产品的升级,MemoryCache 已经不能满足需求,用户需要的 ImageLoader 可将图片同时缓存到内存和 SD 卡中,或者可以让用户自定义实现缓存。下面对 ImageLoader 重构。
ImageCache 缓存接口:
/**
* 图片缓存接口,用来抽象图片缓存的功能
*/
public interface ImageCache {
public Bitmap get(String url);
public void put(String url, Bitmap bitmap);
}
ImageLoader类:
public class ImageLoader{
//图片缓存类,依赖于抽象,并且有一个默认实现
ImageCache mCache = new MemoryCache();
//加载图片
public void displayImage(String url, ImageView imageView){
}
/**
* 设置缓存策略,依赖于抽象
*/
public void setImageCache(ImageCache imageCache) {
mCache = imageCache;
}
}
我们建立了 ImageCache 抽象,并且让 ImageLoader 依赖于抽象而不是具体细节。当需求发送变化时,只需实现 ImageCache 类或者继承其他已有的 ImageCache 之类完成相应的缓存功能,然后将具体的实现注入到 ImageLoader 即可实现缓存功能的替换,这就保证了缓存系统的高可扩展性,有了拥抱变化的能力,这几是依赖倒置原则。
网友评论