美文网首页
6大设计原则-接口隔离原则

6大设计原则-接口隔离原则

作者: stayiwithime | 来源:发表于2019-04-30 16:32 被阅读0次

接口隔离原则

  1. 接口隔离原则的定义
  • 再讲接口隔离原则之前,先明确一下我们的主角——接口。接口分为两种:
    1. 实例接口(Object Interface),在java中声明一个类,然后new一个实例,他是对一个类型的事物的描述,这是一种接口。比如你定义Person这个类,然后使用Person zhangsan = new Person()产生一个实例,这个实例要遵从的标准就是Person这个类。这个地方与java语言定义的接口不太一样,换个思路可能比较清楚,我们从 面向接口编程的设计角度去思考,把java类看做是一个接口。java中接口是语法的定义。
    2. 类接口(Class Interface),java中经常使用的interface关键词定义的接口。
  • 主角已经定义了,那什么是隔离呢?他有两种定义:
    1. 客户端不应该依赖它不需要的接口;
    2. 类间的依赖关系应该建立在最小的接口上。

先说第一种,简单的说就是客户端不需要的接口就剔除掉,客户端需要什么接口就提供什么接口,那这样就需要对接口进行细化,第二种就是建立的接口尽量单一,不要将过多的内容放在一个接口里面,也就是接口尽量细化(就拿我最近的一个例子来说,做amazon广告那块,需要同步amaozn后台的数据,但这个是后台程序跑的不需要暴露给用户使用,用户只需要查看同步过来的数据结果并不需要关心同步的过程,那么我可以分为两个service来完成这个业务,一个留给客户查询,一个实现同步的业务
那些定义说不太清楚,上栗子:
就拿星探发现美女这一场景来说,首先得知道定义美女的条件:脸蛋,身材,气质,那么类图4-1:

4-1
代码如下:
public interface IPettyGirl {
    //脸好看
    void goodLooking();
    //身材好
    void niceFigure();
    //气质好
    void greatTemperamennt();
}
public class PettyGirl implements IPettyGirl {
    private String name;
    public PettyGirl(String name){
        this.name = name;
    }
    @Override
    public void goodLooking() {
        System.out.println(this.name+"---脸蛋很漂亮!");
    }

    @Override
    public void niceFigure() {
        System.out.println(this.name+"---身材非常棒!");
    }

    @Override
    public void greatTemperamennt() {
        System.out.println(this.name+"---气质非常好!");
    }
}
public abstract class AbstractSearcher {
    protected IPettyGirl pettyGirl;
    AbstractSearcher(IPettyGirl pettyGirl){
        this.pettyGirl = pettyGirl;
    }
    public abstract void show();
}
public class Searcher extends AbstractSearcher {
    public Searcher(IPettyGirl pettyGirl){
        super(pettyGirl);
    }
    @Override
    public void show() {
        System.out.println("---美女信息如下---");
        //展示面容
        super.pettyGirl.goodLooking();
        //展示身材
        super.pettyGirl.niceFigure();
        //展示气质
        super.pettyGirl.greatTemperamennt();
    }
}
public class Client {
    public static void main(String[] args) {
        IPettyGirl yanran = new PettyGirl("嫣然");
        AbstractSearcher searcher = new Searcher(yanran);
        searcher.show();
    }
}

这个程序的运行结果都很正常,但是审美这个东西不是一个一直不变的东西,随着审美观的变化,那么对美女的定义也是在变化,相信大部分人都会把脸蛋和身材一般但是气质好的女孩也认为是美女,但是我们接口是需要满足三个条件才认为是美女,如果我们去重新拓展一个美女类只实现greatTemperament方法,其他两个方法置空,那么打印的信息会少两条,那判断的逻辑就会被动改变,那就优化一下,类图4-2:


4-2

这样就把IPettyGirl接口拆分为了两个,将两种不同的审核标准拆分开来了,pettyGirl可以分别实现两个接口也可以同时实现两个接口,都会满足美女这个定义。那如果要再将脸蛋和身材在拆分,那就看有没有实际需要,如果只是为了拆分而拆分那完全没必要,隔离也最好是有限度的,还是那句话,具体场景具体对待。这样就提高的系统的灵活性和可维护性。

  1. 保证接口的纯洁性

接口的隔离原则是对接口进行规范约束,其包含以下4层含义:

  • 接口要尽量小
    这是接口隔离原则的核心定义,不出现臃肿的接口,但小是有限度的,首先不能违反单一职责原则,我们在单一原则中提到一个IPhone的例子,在这里,我们使用单一职责原则吧两个职责分解到两个接口中,类图4-3:
    4-3
    仔细分析一下IConnectionManager接口是否还可以继续拆分下去,那挂电话有两种方式:一种正常,一种异常,那我们要把这个接口拆分吗,从业务逻辑上来讲,通信建立和关闭已经是最小的业务单位了,在这种情况下,根据接口隔离原则拆分接口时,首先必须满足单一职责原则
    这些设计原则其实通过实际的开发中又遇到会印象更深,但前提是你得知道有这么个东西,做好程序员任重道远,得不停的补充自己的知识库
  • 接口要高内聚
    什么事高内聚?高内聚就是提高接口,类,模块的处理能力,减少对外的交互。具体到接口的隔离原则就是,要求接口尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险也就越少,同时也有利于降低成本(个人理解就是,尽量只暴露需要暴露的接口,暴露的接口越多,改动的可能性更大,那么风险就跟大,如果客户端需要实现一个功能,接口只返回必要的结果,实现在内部,不用去暴露给客户端,那么客户端就没有机会去在执行的时候去操作相关的东西导致结果异常,也就降低了风险
  • 定制服务
    一个系统或系统的模块之间必然会有耦合,有耦合就要有相互访问的接口(并不一定只java中定义的interface,也有可能是一个类或单纯的数据交换),我们设计时就需要为各个访问则定制服务,定制服务指的是只提供访问者需要的方法(咋感觉也是高内聚的表现),举个栗子,比如开发图书管理系统,其中有一个接口,方便管理员查询图书,类图4-4:
    4-4
    在接口中定义了多个查询方法,可以按照作者,标题,出版社,分类进行查询,最后还提供了混合查询方式。程序写好了,发现普通用户也可以使用混合查询,本来混合查询是提供给管理员使用的方法,然后这个方法暴露给了普通用户。然后把这个接口进行重构,将IBookeSearcher拆分为两个接口,分别为两个模块提供 定制服务,修改后类图4-5:
    4-5
    那么管理员实现两个接口,普通用户实现一个ISimpleBookSearcher接口就好了。
  • 接口的设计是有限度的
    接口的设计粒度越小,系统越灵活,这是不争的事实。但是过度的设计也带来了结构的复杂化,人为增加了开发难度,总之合适的才是最好的(万金油金句,放诸四海皆准
    具体怎么更好的使用这些设计原则,还是的多看多实践,像spring这些经典的框架肯定会有很多地方实现这些设计原则的,不积跬步无以至千里,丰富的经验都来自积累和实践。

内容来自《设计模式之禅》

相关文章

网友评论

      本文标题:6大设计原则-接口隔离原则

      本文链接:https://www.haomeiwen.com/subject/jhamnqtx.html