面向对象的接口隔离原则

本文探讨了接口隔离原则(ISP)在Java编程中的应用,通过优化关闭资源的代码示例,介绍了CloseUtils工具类的设计思路,展示了如何遵循ISP原则减少代码耦合,提高系统灵活性。

声明:本系列博客整理来源于《Android源码设计模式解析与实战》,仅作为个人学习总结记录,任何组织和个人不得转载进行商业活动!

 

 

接口隔离原则(Interface Segregation Principle,ISP)

ISP的定义是:客户端不应该依赖它不需要的接口。另一种定义是:类间的依赖关系应该建立在最小的接口上。接口隔离原则将非常庞大、臃肿的接口拆分成更小的和更具体的接口,这样客户将会只需要知道他们感兴趣的方法。接口隔离原则的目的是系统解开耦合,从而容易重构、更改和重新部署。

在Java6以及之前的JDK版本,在使用了OutputStream或者其他可关闭的对象之后,我们必须保证它们最终被关闭了,在SD缓存类中有这样的代码:

    //将图片缓存到内存中
    public void put(String url,Bitmap bitmap){
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(cacheDir+url);
            bitmap.compress(Bitmap.CompressFormat.PNG,100,fileOutputStream)
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(fileOutputStream != null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } // end if
        } // end if finally
    }

我们看到的这段代码可读性非常差,各种try...catch嵌套都是些简单的代码,但是会严重影响代码的可读性,并且多层级的大括号很容易将代码写到错误的层级中。大家应该对这类代码也非常反感,那我们看看该如何解决这类问题。

我们可能知道Java中有一个Closeable接口,该接口标识了一个可关闭的对象,它只有一个close方法,如下所示:

其中FileOutputStream类就实现了这个接口。从图中我们可以看到,还有100多个类实现了Closeable这个接口,这意味着,在关闭这100多个类型的对象时,都需要写出像put方法中finally代码段那样的代码。所以,需要进行优化做法,小民想到解决问题的方法,既然都是实现了Closeable接口,就建一个方法来统一关闭这些对象,使用工具类:

public final class CloseUtils {
    private CloseUtils(){}

    /**
     * 关闭Closeable对象
     * @param closeable
     */
    public static void closeQuitely(Closeable closeable){
        if(closeable != null){
            try {
                closeable.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

然后,将这个工具类应用到上面的put方法中:

    //将图片缓存到内存中
    public void put(String url,Bitmap bitmap){
        FileOutputStream fileOutputStream = null;
        try {

            fileOutputStream = new FileOutputStream(cacheDir+url);
            bitmap.compress(Bitmap.CompressFormat.PNG,100,fileOutputStream);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            CloseUtils.closeQuitely(fileOutputStream);
        }

    }

这样可以看到,代码简洁了很多!而且这个closeQuietly方法可以运用到各类可关闭的对象中,保证了代码的重用性。CloseUtils的closeQuietly方法的基本原理就是依赖于Closeable抽象而不是具体实现,这正满足了依赖倒置原则,并且建立在最小化依赖原则的基础上,它只需要知道这个对象是可关闭的,其他的一概不用关心,这也是接口隔离原则。

试想一下,如果在只是需要关闭一个对象时,它却暴露出了其他的接口函数,如OutputStream的write方法,这就使得更多的细节暴露在客户端代码面前,不仅没有很好地隐藏实现,还增加了接口的使用难度。而通过Closeable接口将可关闭的对象抽象起来,这样只需要客户端依赖于Classable就可以对客户端隐藏其他的接口信息,客户端代码只需要知道这个对象可关闭(只可调用close方法)即可。小民设计的ImageLoader中的ImageCache就是接口隔离原则的运用,ImageLoader只需要知道该缓存对象有存、取缓存图片的接口即可,其他的一概不管,这就使得缓存功能的具体实现对ImageLoader隐藏。这就是最小化接口隔离了实现类的细节,也促使我们将庞大的接口拆分到更细粒度的接口当中,这使得我们的系统具有更低的耦合性,更高的灵活性。

Bob大叔(Robert C Martin)在21世纪早期将单一职责、开闭原则、里氏替换、接口隔离以及依赖倒置5个原则定义为SOLID原则,作为面向对象编程的5个基本原则。当这些原则被一起使用时,它们使得软件系统更清晰、简单,最大程度地拥抱变化。SOLID被典型地应用在软件驱动开发上,并且是敏捷开发以及自适应软件开发基本原则的重要组成部分。在通过这前五个原则的学习之后,我们发现这几大原则最终就可以化为这个关键词:抽象、单一职责、最小化。那么,在实际开发中如何权衡、实践这些原则,大家需要在实践中多思考与领悟,正所谓“学而不思则罔,思而不学则怠”,只有不断地学习、实践、思考,才能够在积累的过程中有一个质的飞跃。

 

 

<<点击 - 面向对象的依赖倒置原则
点击 - 面向对象的迪米特原则>>

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值