天天看点

《Android 源码设计模式解析与实战》——第1章,第1.5节系统有更高的灵活性——接口隔离原则

本节书摘来自异步社区《android 源码设计模式解析与实战》一书中的第1章,第1.5节系统有更高的灵活性——接口隔离原则,作者 何红辉 , 关爱民,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.5 系统有更高的灵活性——接口隔离原则

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

接口隔离原则说白了就是,让客户端依赖的接口尽可能地小,这样说可能还是有点抽象,我们还是以一个示例来说明一下。在此之前我们来说一个场景,在java 6以及之前的jdk版本,有一个非常讨厌的问题,那就是在使用了outputstream或者其他可关闭的对象之后,我们必须保证它们最终被关闭了,我们的sd卡缓存类中就有这样的代码:

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

我们可能知道java中有一个closeable接口,该接口标识了一个可关闭的对象,它只有一个close方法,如图1-4所示。

我们要讲的fileoutputstream类就实现了这个接口。我们从图1-4中可以看到,还有100多个类实现了closeable这个接口,这意味着,在关闭这100多个类型的对象时,都需要写出像put方法中finally代码段那样的代码。这还了得!你能忍,反正小民是忍不了的!于是小民打算要发挥他的聪明才智解决这个问题,既然都是实现了closeable接口,那只要我建一个方法统一来关闭这些对象不就可以了么?说干就干,于是小民写下来如下的工具类:

《Android 源码设计模式解析与实战》——第1章,第1.5节系统有更高的灵活性——接口隔离原则

我们再看看把这段代码运用到上述的put方法中的效果如何:

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

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

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

继续阅读