举例说明Java设计模式编程中ISP接口隔离原则的使用_java

Interface Segregation Principle,ISP接口隔离原则主张使用多个专门的接口比使用单一的总接口要好。
一个类对另外一个类的依赖性应当是建立在最小的接口上的。
一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。
“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。

使用场合,提供调用者需要的方法,屏蔽不需要的方法.满足接口隔离原则.比如说电子商务的系统,有订单这个类,有三个地方会使用到,

  1. 一个是门户,只能有查询方法,
  2. 一个是外部系统,有添加订单的方法,
  3. 一个是管理后台,添加删除修改查询都要用到.

根据接口隔离原则(ISP),一个类对另外一个类的依赖性应当是建立在最小的接口上.

也就是说,对于门户,它只能依赖有一个查询方法的接口.
UML结构如下:

我们来看一个无视接口隔离原则的Java接口编写例子:

interface I {
  public void method1();
  public void method2();
  public void method3();
  public void method4();
  public void method5();
} 

class A{
  public void depend1(I i){
    i.method1();
  }
  public void depend2(I i){
    i.method2();
  }
  public void depend3(I i){
    i.method3();
  }
} 

class B implements I{
  public void method1() {
    System.out.println("类B实现接口I的方法1");
  }
  public void method2() {
    System.out.println("类B实现接口I的方法2");
  }
  public void method3() {
    System.out.println("类B实现接口I的方法3");
  }
  //对于类B来说,method4和method5不是必需的,但是由于接口A中有这两个方法,
  //所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。
  public void method4() {}
  public void method5() {}
} 

class C{
  public void depend1(I i){
    i.method1();
  }
  public void depend2(I i){
    i.method4();
  }
  public void depend3(I i){
    i.method5();
  }
} 

class D implements I{
  public void method1() {
    System.out.println("类D实现接口I的方法1");
  }
  //对于类D来说,method2和method3不是必需的,但是由于接口A中有这两个方法,
  //所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。
  public void method2() {}
  public void method3() {} 

  public void method4() {
    System.out.println("类D实现接口I的方法4");
  }
  public void method5() {
    System.out.println("类D实现接口I的方法5");
  }
} 

public class Client{
  public static void main(String[] args){
    A a = new A();
    a.depend1(new B());
    a.depend2(new B());
    a.depend3(new B()); 

    C c = new C();
    c.depend1(new D());
    c.depend2(new D());
    c.depend3(new D());
  }
}

        可以看到,如果接口过于臃肿,只要接口中出现的方法,不管对依赖于它的类有没有用处,实现类中都必须去实现这些方法,这显然不是好的设计。如果将这个设计修改为符合接口隔离原则,就必须对接口I进行拆分。在这里我们将原有的接口I拆分为三个接口,拆分后的设计如下图所示:

照例贴出程序的代码,供不熟悉类图的朋友参考:

interface I1 {
  public void method1();
} 

interface I2 {
  public void method2();
  public void method3();
} 

interface I3 {
  public void method4();
  public void method5();
} 

class A{
  public void depend1(I1 i){
    i.method1();
  }
  public void depend2(I2 i){
    i.method2();
  }
  public void depend3(I2 i){
    i.method3();
  }
} 

class B implements I1, I2{
  public void method1() {
    System.out.println("类B实现接口I1的方法1");
  }
  public void method2() {
    System.out.println("类B实现接口I2的方法2");
  }
  public void method3() {
    System.out.println("类B实现接口I2的方法3");
  }
} 

class C{
  public void depend1(I1 i){
    i.method1();
  }
  public void depend2(I3 i){
    i.method4();
  }
  public void depend3(I3 i){
    i.method5();
  }
} 

class D implements I1, I3{
  public void method1() {
    System.out.println("类D实现接口I1的方法1");
  }
  public void method4() {
    System.out.println("类D实现接口I3的方法4");
  }
  public void method5() {
    System.out.println("类D实现接口I3的方法5");
  }
}

        接口隔离原则的含义是:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。本文例子中,将一个庞大的接口变更为3个专用的接口所采用的就是接口隔离原则。在程序设计中,依赖几个专用的接口要比依赖一个综合的接口更灵活。接口是设计时对外部设定的“契约”,通过分散定义多个接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
         说到这里,很多人会觉的接口隔离原则跟之前的单一职责原则很相似,其实不然。其一,单一职责原则原注重的是职责;而接口隔离原则注重对接口依赖的隔离。其二,单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;而接口隔离原则主要约束接口接口,主要针对抽象,针对程序整体框架的构建。
         采用接口隔离原则对接口进行约束时,要注意以下几点:
接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
运用接口隔离原则,一定要适度,接口设计的过大或过小都不好。设计接口的时候,只有多花些时间去思考和筹划,才能准确地实践这一原则。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 设计模式
接口隔离原则
接口隔离原则 举例、isp编程、isp编程器、isp在线编程、isp原则,以便于您获取更多的相关知识。

时间: 2024-08-03 17:34:48

举例说明Java设计模式编程中ISP接口隔离原则的使用_java的相关文章

举例讲解Java设计模式编程中Decorator装饰者模式的运用_java

概念 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型. 你可以用一个或多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合 ,可以用装饰过的对象代替它. 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的. 对象可以在任何时候被装饰,所以可以在运行时动态地.不限量地用你喜欢的装饰者来装饰 对象. 在Java中,io包下的很多类就是典型的装饰

Java设计模式编程中的责任链模式使用示例_java

责任链模式:多个对象由其对象对应下家的引用连成一条链,请求在这个链上传递,直到 链上的某一个接收对象处理此请求.因为请求的客户端并不知道链上最终是谁来处理这个请求,使得系统可以在不影响客户端的情况下动态地重新组织和分配责任, 从而避免了请求发送者与请求处理者之间的耦合. 责任链械中涉及到三种角色: 1,抽象处理者角色 2,具体处理者角色 3,请求发送者 小例子:假设去买房子,买房子就需要砍价, 卖房的人职位不同,可以优惠的价格也不同,不同职位就可以形成一个处理请求的链.我们暂定: * 基层销售员

理解Java设计模式编程中的迪米特原则_java

定义:一个对象应该对其他对象保持最少的了解. 问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大. 解决方案:尽量降低类与类之间的耦合.          自从我们接触编程开始,就知道了软件编程的总的原则:低耦合,高内聚.无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率.低耦合的优点不言而喻,但是怎么样编程才能做到低耦合呢?那正是迪米特法则要去完成的.          迪米特法则又叫最少知道原则,最早是在1987年

举例讲解Java设计模式编程中模板方法模式的运用实例_java

模板方法模式定义为: 在一个方法中定义了一个算法的骨架或者步骤,而将一些步骤延迟到子类中去实现.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某一些步骤. 模板方法在基类中定义了一个操作的流程顺序,能够保证该步骤按序进行,有一些步骤的具体实现在基类中已经声明,而将一些变化的步骤的具体实现交给了子类去实现,从而就达到了延迟一些步骤到子类中,模板方法一个最大的好处就是能够设定一个业务流程能够按照一定严格的顺序执行,控制了整个算法的执行步骤. 这个方法将算法定义成一组步骤,其中凡是想让

详解Java设计模式编程中的依赖倒置原则_java

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一般是高层模块,负责复杂的业务逻辑:类B和类C是低层模块,负责基本的原子操作:假如修改类A,会给程序带来不必要的风险. 解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率.          依赖倒置原则基于这样一个事实:相

简单讲解Java设计模式编程中的单一职责原则_java

单一职责原则:一个类,只有一个引起它变化的原因. 为什么需要单一职责原则? 如果一个类有多个原因要去修改它,那么修改一个功能时,可能会让其他功能产生Bug,所以一个类最好只有一个职责.但实际应用中还是比较难实现的,我们只能是尽量符合这个原则. 有时候,开发人员设计接口的时候会有些问题,比如用户的属性和用户的行为被放在一个接口中声明.这就造成了业务对象和业务逻辑被放在了一起,这样就造成了这个接口有两种职责,接口职责不明确,按照SRP的定义就违背了接口的单一职责原则了. 下面是个例子: packag

详解Java设计模式编程中命令模式的项目结构实现_java

正论: 命令模式把一个请求或者操作封装到一个对象中.命令模式运行系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 通俗: 其实很好理解.命令模式,关心的就是命令(或者称为操作).打个比方.在一个公司里面,整个运作就像一个系统.某个boss发布了一个命令,中层领导接到这个命令,然后指派给具体负责这个员工.整个流程很清晰吧.有一个需求,如何将这个流程固定下来,形成一个系统.我们只要抓住了重点:命令.将它抽取出来,其他的都迎刃而解了.抽取出命令,封装成一个独

浅析Java设计模式编程中的单例模式和简单工厂模式_java

单例模式动机 有时候只有一个类的实例是很重要的.比如,一个系统应该只有一个窗口管理实例. 单例模式是最简单设计模式:类负责实例化自己,确保只有一个实例,并且提供一个访问这个实例的入口. 目的 1. 确保只有一个实例被创建. 2. 提供访问这个实例的入口. 使用final确保被创建一次,private的构造函数确保不被实例化.public的getInstance方法确保外部能够访问.下面是饿汉模式: public class Singleton { private static final Sin

详解Java设计模式编程中的策略模式_java

定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换.类型:行为类模式类图: 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过的行为类模式中,有一种模式也是关注对算法的封装--模版方法模式,对照类图可以看到,策略模式与模版方法模式的区别仅仅是多了一个单独的封装类Context,它与模版方法模式的区别在于:在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主体则是封装到了封装类Context中,抽