面向接口編程與策略模式

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關鍵字這么簡單??梢岳斫鉃榻涌谑菍唧w實現的抽象。試想一下,團隊協同以及代碼健壯可維護性的需求日益增強的趨勢下,通過暴露接口來提供服務本身是一件非常愉悅的事情。A需要調用B中的服務,A卻不需要去仔細閱讀B寫的代碼,通過接口文檔就可以看出對應業務的方法和參數類型,進而使用RMI或者RPC等相關技術實現模塊化調用。而這一切本身就是面向接口編程

abstract class 和 interface

為什么有這樣的問題呢?很多剛接觸面向接口編程的Java開發者都或多或少遇到這樣的困惑。他們大多會認為,既然是面向接口編程,那么把實現抽象為接口就是優良的設計。但實際上他們混淆了Java中的interface和面向接口編程中的“接口”概念。實際上,interface、abstract 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和具體實現類之間起到了很好的過渡效果。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容