使用Adapter和Interface提高方法的複用性

假如說現在需要設計一個打印機,要適配不同的打印模式(API),然後還要按照不同的控件佈局輸出你想要的排版,解決這個問題我們只用瞭解Adapter和Bridge的設計,在我之前的博客裏已經討論過控件和實體數據(也是適配器提供的結果)的分離,今天看了《Java編程思想》關於Complete decoupling的章節,其中使用Adapter和Interface來實現完全解耦可以解決打印機對不同API的適配。

由於這種模式也是根據需求,人們慢慢總結出來的,所以我們先從最簡單的需求說起:

  • 1

實現父類與子類的信息傳遞,必然會用到向上轉型。假如我們要讓一個接口根據獲取的參數不同而又不同的行爲,可以寫一個父類,然後讓子類重寫父類的方法(須是public的),那麼在類外的方法會根據不同的子類向上轉型,使用子類的特定方法(友情提示:要使用父類的方法需要加關鍵字super)。

package interfaces.classprocessor;
import java.util.*;
class Processor{
    public String name(){
        return getClass().getSimpleName();
    }
    //子類中重寫次此方法時用其他類型如string  int 等
    Object process(Object input){
        return input;
    }
}
class Upcase extends Processor{
    String process(Object input){
        return ((String)input).toUpperCase();
    }
}
class Downcase extends Processor{
    String process(Object input){
        return ((String)input).toLowerCase();
    }
}
class Splitter extends Processor{
    String process(Object input){
        return Arrays.toString(((String)input).split(" "));
    }
}
public class Apply{
    public static void process(Processor p,Object s){
        System.out.println("Using Processor"+p.name());
        System.out.println(p.process(s));
    }
    public static String s="this is a Sup--Sub Coupling";
    public static void main(String[] args){
        process(new Upcase(),s);
        process(new Downcase(),s);
        process(new Splitter(),s);
    }
}

Apply.process()方法可以接收Processor的子類(向上轉型),並且在方法裏調用子類重寫的父類方法process(),以不同方式輸出字符串s。這種模式叫”策略設計模式”。其實就是利用多態的特性,但是Apply.process()和Processor類的耦合性太強了,如果此時遇到新的需求,封裝成類Filter,而這個類只有少部分(比如一個函數參數)與Processor類不同,那麼就要再寫一個Filter類來作爲父類,而且此時Apply.process()方法也不能使用Filter類,可見Apply.process()的複用性不強。

  • 2

既然Processor有許多實現,那麼可以將其寫成接口,Filter類可以implements Processor接口,根據需求重寫其process()方法,而該重寫的方法依然保留抽象屬性(這裏的重寫就是保證方法簽名與Processor接口相同,改變其返回值,比如返回String類型。當然也可以都不改變。),再讓其子類來根據需求實現方法的具體功能,這樣Apply.process()的複用性就加強了。

  • 3

上面說的Filter是繼承已有接口Processor,如果我們想用的並不是創建(created)出來的接口,而是來自外部類庫,不能修改,還是有辦法實現Filter接口與Apply.process()方法的解耦合。文章開頭提到的Adapter模式可以使用了,如果有多種於Processor類似的接口需要適配Apply.process()方法,就將它們統一到已有接口Processor:

package interfaces.interfaceprocessor;
import interfaces.filter.*;
class FilterAdapter implements Processor{
        Filter filter;
       public FilterAdapter(Filter filter){
             this.filter=filter;
      }       
      public String name(){return filter.name();}
      public Waveform process(Object input){
           return filter.process((Waveform)input);
      }
}

Filter和Waveform分別是import自interfaces.filter包的接口和類,不能被修改,而適配該lib的適配器封裝了filter實例,根據filter需求(注意返回值類型已經被重寫爲Waveform)實現了Processor的方法,所以可以被Apply.process()使用,實現了接口和方法的完全解耦!

代碼轉自java利用接口和適配器進行完全解耦–參考《thinking in java》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章