面向对象基本原则 - 里氏替换 - 依赖倒置

里氏替换原则

简单来说就是,所有引用基类的地方,都能替换成对应的子类,也就是说父类能出现的地方,都能够用子类来替换

例如:

public class Window {
    public void show(View child){
        child.draw();
    }
}

//抽象基类
public abstract class View {
    public abstract void draw();
    public void measure(int width ,int height){
        //测量大小,统一处理
    }
}

public class TextView extends View {
    @Override
    public void draw() {
        //绘制 TextView
    }
}

public class Button extends View {
    @Override
    public void draw() {
        //绘制 button
    }
}

如上,Window类依赖View,而View是所有视图的抽象基类,measure()方法是子类共享的,draw() 方法是抽象的,子类自己实现各种各样的绘制功能. 这里任何继承自 View 的子类都可以设置给Window来显示出来

原来,里氏替换原则的核心是抽象和继承; 利用抽象和继承,可以把共享的内容统一处理,把差异的抽象,通过继承让子类来实现

依赖倒置原则

依赖倒置原则有以下几个特点:
(1). 调用者不应该直接依赖具体实现类,两者都应该依赖对应的抽象
(2).抽象中不应该直接依赖具体的实现类
(3).实现类应该依赖抽象

也就是说,两个实现类之间通过抽象类或者接口来关联,两个实现类不发生直接的依赖关系

例如:

public class ImageLoader {
    //默认实现
    private MemoryCache mImageCache = new MemoryCache();

    public void setImageCache(MemoryCache cache){
        mImageCache = cache;
    }
    public void displayImage( String url, ImageView imageView) {
        Bitmap bitmap = mImageCache.get(url);
        if(bitmap == null){
            downloadImage(url,imageView);
        }else {
            imageView.setImageBitmap(bitmap);
        }
    }
}

这里ImageLoaderMemoryCache就直接发生了依赖关系,当想要改变缓存策略的时候,要添加一个SD缓存,或者双缓存,这个时候不但要改缓存类,同时也要修改ImageLoader这个类

遵循依赖倒置原则,两个类不应该直接依赖,修改为:

public class ImageLoader {
    //通过引用抽象来依赖
    private ImageCache mImageCache = new MemoryCache();

    public void setImageCache(ImageCache cache){
        mImageCache = cache;
    }
    public void displayImage( String url, ImageView imageView) {
        Bitmap bitmap = mImageCache.get(url);
        if(bitmap == null){
            downloadImage(url,imageView);
        }else {
            imageView.setImageBitmap(bitmap);
        }
    }
}

只需要把原来的变量mImageCache的类型MemoryCache改为抽象ImageCache通过引用抽象来发生依赖,setImageCache(ImageCache cache)也是直接传入抽象,当需要改变缓存策略的时候,只需要修改对应的抽象实现就行,不会影响到ImageLoader的内部逻辑代码.保证了缓存系统的可扩展性,拥有变化的能力,这就是依赖倒置原则

可以看出来,在面向对象语言里面,抽象是非常重要的一种手段

你可能感兴趣的:(面向对象基本原则 - 里氏替换 - 依赖倒置)