面向接口编程与策略模式

作者: 叫我匠人 | 来源:发表于2016-06-13 10:36 被阅读1284次
    oop.jpg

    面向接口编程 & 面向对象编程

    Interface-based programming, also known as interface-based architecture, is an architectural pattern for implementing modular programming at the component level in an object-oriented programming language which does not have a module system. (面向接口编程,也被熟知为基于接口的设计,是一种基于组件级别的,面向对象语言的模块化编程设计实现)

    面向接口编程和面向对象编程实际上是两个不同层级的概念。理论上说具有对象概念的程序设计都可以称之为面向对象编程,而面向接口编程则是从组件的级别来设计代码,人为地将抽象与实现分离。面向接口编程仅仅只是面向对象编程的一种模块化实现形式而已。

    所谓“接口”

    面向接口编程中的"接口"二字具体到语言中(Java)不仅仅是interface关键字这么简单。可以理解为接口是对具体实现的抽象。试想一下,团队协同以及代码健壮可维护性的需求日益增强的趋势下,通过暴露接口来提供服务本身是一件非常愉悦的事情。A需要调用B中的服务,A却不需要去仔细阅读B写的代码,通过接口文档就可以看出对应业务的方法和参数类型,进而使用RMI或者RPC等相关技术实现模块化调用。而这一切本身就是面向接口编程

    abstract class 和 interface

    为什么有这样的问题呢?很多刚接触面向接口编程的Java开发者都或多或少遇到这样的困惑。他们大多会认为,既然是面向接口编程,那么把实现抽象为接口就是优良的设计。但实际上他们混淆了Java中的interface和面向接口编程中的“接口”概念。实际上,interfaceabstract class以及普通的class都能成为所谓的接口,甚至abstract class的功能可以更加强大。那么问题来了,interfaceabstract class分别对应于什么场景下使用更合适一些?
    interfaceabstract class区别在于interface约定的是务必要实现的方法和参数,强调规则的制定;abstract class则在抽象的同时允许提供一些默认的行为,以达到代码复用的效果。例如定义一些基础、初始化以及类回收方法等。另外,还有一个常识性的区别,一个实现类(相对于抽象而言)可以实现多个interface,而只能继承一个abstract class,在代码设计的过程中务必注意。

    策略模式 (Strategy Pattern)

    作为面向接口编程的一个典型设计模式,应用相当普遍。本文之所以讨论策略模式,是该模式本身把“面向接口编程”思想很好地体现了。这里举个简单的例子以供参考。

    //定义策略接口
    interface Strategy { public void solve(); }
    /**************   策略一   **************/
    //策略1抽象类
    abstract class TemplateMethod1 implements Strategy {
       public void solve() {
          start();
          while (nextTry() && ! isSolution())
             ;
          stop();
       }
       protected abstract void    start();
       protected abstract boolean nextTry();
       protected abstract boolean isSolution();
       protected abstract void    stop();
    }
    //策略1实现类
    class Impl1 extends TemplateMethod1 {
       private int state = 1;
       protected void start() {
         System.out.print( "start  " );
       }
       protected void stop() {
         System.out.println( "stop" );
       }
       protected boolean nextTry() {
          System.out.print( "nextTry-" + state++ + "  " );
          return true;
       }
       protected boolean isSolution() {
          System.out.print( "isSolution-" + (state == 3) + "  " );
          return (state == 3);
       }
    }
    /**************   策略二   **************/
    //策略2抽象类
    abstract class TemplateMethod2 implements Strategy {
       public void solve() {                             
          while (true) {
             preProcess();
             if (search()) break;
             postProcess();
          }
       }
       protected abstract void preProcess();
       protected abstract boolean search();
       protected abstract void postProcess();
    }
    //策略2实现类
    class Impl2 extends TemplateMethod2 {
       private int state = 1;
       protected void    preProcess()  { System.out.print( "preProcess  " ); }
       protected void    postProcess() { System.out.print( "postProcess  " ); }
       protected boolean search() {
          System.out.print( "search-" + state++ + "  " );
          return state == 3 ? true : false;
       }
    }
    
    /**************   测试类   **************/
    public class StrategyDemo {
       public static void clientCode( Strategy strat ) {
         strat.solve();
       }
       public static void main( String[] args ) {
          Strategy[] algorithms = { new Impl1(), new Impl2() };
          for (int i=0; i < algorithms.length; i++) {
             clientCode( algorithms[i] );
          }
       }
    }
    
    

    其中interface定义的是最抽象的东西,也就是上文说的规则,但是过度抽象不利于代码的复用。于是abstract class的优势就能很好的利用了。介于绝对抽象和具体实现之间,abstract class既能够实现接口方法,提供一个默认方法支持(所谓“策略”),又能制定出该策略下附带的某些必须实现的抽象方法(所谓“规则”),在interface和具体实现类之间起到了很好的过渡效果。

    相关文章

      网友评论

      • eversky:策略和模板混合的感觉
      • Peter潘的博客:感觉上面写的是模板设计模式,不是策略吧。
      • 有心人问道:学习了,我用的是C#,何时该用接口,何时该用抽象类是我一直纠结的地方。但我想这是相通的,希望我会学的更好吧。
        叫我匠人:@YxrWendao 面向对象的思想肯定是相通的

      本文标题:面向接口编程与策略模式

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