只要一個(gè)方法操作的是類而非接口,那么你就只能使用這個(gè)類及其子類。如果你想要將這個(gè)方法應(yīng)用于不在此繼承結(jié)構(gòu)中的某個(gè)類,那么你就會(huì)倒大霉了。接口可以在很大程序上放寬這種限制,因此它使得我們可以編寫(xiě)可復(fù)用性更好的代碼
首先看,通過(guò)類的繼承實(shí)現(xiàn)的一個(gè)程序

class Processor
{

public String name()
{
return getClass().getSimpleName();
}

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 String s = "Disagredment with beliefs is by definition incorrect";

public static void process(Processor p, Object s)
{
System.out.println("Using Processor "+ p.name());
System.out.println(p.process(s));
}

public static void main(String[] args)
{
process(new Upcase(),s);
process(new Downcase(),s);
process(new Splitter(),s);

}
}
這個(gè)例子很簡(jiǎn)單,只是把字符串轉(zhuǎn)換為大寫(xiě),小寫(xiě)和以空格拆分的字符串。值得注意的是負(fù)責(zé)轉(zhuǎn)換的類Upcase, Downcase和Splitter都是繼承于Processor的,而Processor是一個(gè)普通的類。咋一看是沒(méi)問(wèn)題的,但是要想通過(guò)復(fù)用把以下的別的類似的程序就不方便了

class Waveform
{
private static long counter;
private final long id = counter++;

public String toString()
{
return "Waveform" + id;
}
}

class Filter
{

public String name()
{
return getClass().getSimpleName();
}

public Waveform process(Waveform input)
{
return input;
}
}

class LowPass extends Filter
{
double cutoff;

public LowPass(double cutoff)
{
this.cutoff = cutoff;
}
@Override

public Waveform process (Waveform input)
{
return input;
}
}

class HighPass extends Filter
{
double cutoff;

public HighPass(double cutoff)
{
this.cutoff = cutoff;
}

public Waveform process(Waveform input)
{
return input;
}
}

class BandPass extends Filter
{
double lowCutoff,highCutoff;

public BandPass(double lowCut, double highCut)
{
lowCutoff = lowCut;
highCutoff = highCut;
}
}
因?yàn)樵贏pply.process()方法在傳入的是Processor類,而Filter的創(chuàng)建者壓根不清楚它將要被用作Processor。也許你會(huì)認(rèn)為通過(guò)繼承Process就把問(wèn)題解決了,但是你會(huì)發(fā)現(xiàn)Filter.process和Process.process的方法簽名是不一樣的,那就是說(shuō)Filter并沒(méi)有覆蓋Process的方法,這樣將會(huì)導(dǎo)致不安全性(Filter因繼承而多了一個(gè)不在設(shè)計(jì)范圍內(nèi)的方法)。因此使得代碼復(fù)用就很難了,主要的原因是Apply.process()和Process之間的耦合太緊了。如果把Processor改為接口,這些限制就會(huì)變得松動(dòng)了

interface Processor
{
String name();
Object process(Object input);
}
//把導(dǎo)出類的name方法抽取出來(lái)單獨(dú)設(shè)置一個(gè)abstract類

abstract class StringProcessor implements Processor
{

public String name()
{
return getClass().getSimpleName();
}
public abstract String process(Object input);
}

class Upcase extends StringProcessor
{
@Override

public String process(Object input)
{
return ((String)input).toUpperCase();
}
}

class Splitter extends StringProcessor
{
@Override

public String process(Object input)
{
return Arrays.toString(((String)input).split(" "));
}
}

class Downcase extends StringProcessor
{
@Override

public String process(Object input)
{
return ((String)input).toLowerCase();
}
}

public class Apply
{
public static String s = "Disagredment with beliefs is by definition incorrect";

public static void process(Processor p, Object s)
{
System.out.println("Using Processor "+ p.name());
System.out.println(p.process(s));
}

public static void main(String[] args)
{
process(new Upcase(), s);
process(new Downcase(),s);
process(new Splitter(),s);
}
}
這種我們就可以通過(guò)實(shí)現(xiàn)接口而在復(fù)用的基礎(chǔ)上加入Filter了

abstract class Filter implements Processor
{

public String name()
{
return getClass().getSimpleName();
}

public abstract Waveform process(Object input);
}

class BandPass extends Filter
{
double lowCutoff,highCutoff;

public BandPass(double lowCut, double highCut)
{
lowCutoff = lowCut;
highCutoff = highCut;
}
@Override

public Waveform process(Object input)
{
return (Waveform) input;
}
}

class HighPass extends Filter
{
double cutoff;

public HighPass(double cutoff)
{
this.cutoff = cutoff;
}
@Override

public Waveform process(Object input)
{
return (Waveform) input;
}
}

class LowPass extends Filter
{
double cutoff;

public LowPass(double cutoff)
{
this.cutoff = cutoff;
}
@Override

public Waveform process (Object input)
{
return (Waveform) input;
}
}

public class Apply
{
public static String s = "Disagredment with beliefs is by definition incorrect";

public static void process(Processor p, Object s)
{
System.out.println("Using Processor "+ p.name());
System.out.println(p.process(s));
}

public static void main(String[] args)
{
//process(new Upcase(), s);
//process(new Downcase(),s);
//process(new Splitter(),s);
Waveform w = new Waveform();
process(new LowPass(1.0),w);
process(new HighPass(3.0),w);
process(new BandPass(1.0,2.0),w);
}
}
上面的例子很好說(shuō)明了,不用修改原程序(當(dāng)然Filter還是要改的),可以直接通過(guò)復(fù)用接口Processor和Apply.process()。然后有的時(shí)候Filter并不是可以修改的,或者你得到的只是一個(gè)類庫(kù),這個(gè)時(shí)候可以使用Adaptor設(shè)計(jì)模式
//Filter不能修改

class Filter
{

public String name()
{
return getClass().getSimpleName();
}
// @Override

public Waveform process(Waveform input)
{
return input;
}
}
//Filter的Adapter

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);
}

}public class Apply
{
public static String s = "Disagredment with beliefs is by definition incorrect";

public static void process(Processor p, Object s)
{
System.out.println("Using Processor "+ p.name());
System.out.println(p.process(s));
}

public static void main(String[] args)
{
Waveform w = new Waveform();
process(new FilterAdapter(new chapter9.LowPass(1.0)),w);
process(new FilterAdapter(new chapter9.HighPass(3.0)),w);
process(new FilterAdapter(new chapter9.BandPass(1.0,2.0)),w);
}
}
在這種使用適配器的方式中,F(xiàn)ilterAdapter的構(gòu)造器接受你所擁有的接口Filter,然后生成具有你所需要的Processor接口的對(duì)象。在FilterAdapter中還使用了代理