闲谈设计模式之接口隔离

接口隔离(Interface Segregation Principles)

接口隔离:俗称ISP,其遵循原则就是,类之间的依赖建立在最小接口依赖上,减少不必要的接口,避免接口功能繁重冗余;分割成更小更具体的细化接口。

示例代码分析

结合Android源码设计示例代码分

public class DiskCache implements ImageCache {
    private String filePath = "";
    @Override
    public void put(String url, Bitmap bitmap) {
        //这里写下载图片写入本地图片缓存
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(filePath+url);
            bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (outputStream!=null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

这一段存储文件的代码,看着没有什么问题,但是使用了过多的try catch的代码使得代码很臃肿,熟悉JavaIo的同学,应该会知道JavaIO有一个接口叫做Closeable这样一个接口,他负责了javaIO流关闭的一个抽象接口,通过利用这样一个接口就可以这样去写:

public class CloseTools {

    private CloseTools() { }

    private static class CloseToolsLazy{
        private static final CloseTools tools = new CloseTools();
    }

    public static CloseTools getInstance(){
        return CloseToolsLazy.tools;
    }

    public void close(Closeable closeable){
        if (closeable!=null){
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

public class DiskCache implements ImageCache {
    private String filePath = "";
    @Override
    public void put(String url, Bitmap bitmap) {
        //这里写下载图片写入本地图片缓存
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(filePath+url);
            bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (outputStream!=null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

利用这样一个Closeable 接口,结合单例以及里氏替换原则去优化我们对流关闭的这样一个操作,那为什么说它是符合接口隔离呢,在JavaIO层次上不只有关闭这样一个还有flush等等操作,如果写了一个base接口里面这些IO抽象接口都在这里面,那你可以想象得到每一个IO的具体实现都要实例一些不相干的接口,那么对类的设计来说就是一场灾难。接下来以FileOutputStream源码进行分析。

对JavaIO层FileOutputStream的探讨

先来看一段相关源码:

public class FileOutputStream extends OutputStream{

}

public abstract class OutputStream implements Closeable, Flushable {
    public void flush() throws IOException {
    }

    public void close() throws IOException {
    }
}

public interface Closeable extends AutoCloseable {

    /**
     * Closes this stream and releases any system resources associated
     * with it. If the stream is already closed then invoking this
     * method has no effect.
     *
     * <p> As noted in {@link AutoCloseable#close()}, cases where the
     * close may fail require careful attention. It is strongly advised
     * to relinquish the underlying resources and to internally
     * <em>mark</em> the {@code Closeable} as closed, prior to throwing
     * the {@code IOException}.
     *
     * @throws IOException if an I/O error occurs
     */
    public void close() throws IOException;
}

public interface Flushable {

    /**
     * Flushes this stream by writing any buffered output to the underlying
     * stream.
     *
     * @throws IOException If an I/O error occurs
     */
    void flush() throws IOException;
}

结合部分源码可以得出一组UML类图:

在OutputStream 中flush以及close都是一个空方法,而FileOutputStream则负责实例化他们,为什么Flushable以及Closeable很贴切ISP原则呢?在有些IO流中,有些只需要关注某一个抽象,就像Closeable每一个流基本都会用到,而Flushable则不一定会用到,那么他们两个如果集合到一个接口中去呢?一些不需要用到Flushable接口的IO但是需要Closeable,是不是都要实例化Flushable?所以在JavaIO层中会做到尽量的细话每一个抽象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值