来自java编程思想9.3 完全解耦
只要一个方法操作是类而非接口,那么你就只能使用这个类及其子类。如果你想要将这个方法应用到不在此继承结构中的某个类,那么你就达不到目的。接口可以很大程度放宽这种限制,因此使用接口而非继承使得我们可以编写可复用性更好的代码。PS:书中前面也说道了,慎用继承,尽量使用组合!
例如:假设有一个Processor类,产生一个name()方法;另外还有一个process()方法,该方法接受输入参数,修改它的值产生输入。这个类作为基类被扩展,用来创建不同的Processor。
package interfaces.classprocessor; import static net.mindview.util.Print.*; import java.util.Arrays; 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).toLowerCase(); } } class Downcase extends Processor{ String process(Object input){ return ((String)input).toUpperCase(); } } 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){ print("Using processor "+p.name()); print(p.process(s)); } public static String s = "Disagreement with beliefs is by definition incorrct"; public static void main(String[] args) { process(new Upcase(), s); process(new Downcase(), s); process(new Splitter(), s); } }
Using processor Upcase
disagreement with beliefs is by definition incorrct
Using processor Downcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRCT
Using processor Splitter
[Disagreement, with, beliefs, is, by, definition, incorrct]
Apply.process()方法可以接受任何类型的Processor,并将其应用到一个Object对象上,然后打印结果。像本例刚开始看我们觉得设计是不错的,创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,称为策略模式。这类方法包含执行算法中固定不变的部分,而“策略”包含变化的部分,策略就是传进去的参数。
现在有一个电子滤波器好像也是用Apply.process()方法。
在interfaces.filters包中创建相关的代码
package interfaces.filters; public class Waveform { private static long counter; private static long id = counter++; public String toString(){ return "Waveform" + id; } }
package interfaces.filters; public class Filter { public String name(){ return getClass().getSimpleName(); } public Waveform process(Waveform input){ return input; } }
package interfaces.filters; public class LowPass extends Filter { double cutoff; public LowPass(double cutoff){ this.cutoff = cutoff; } public Waveform process(Waveform input){ return input; } }
package interfaces.filters; public class HighPass extends Filter { double cutoff; public HighPass(double cutoff){ this.cutoff = cutoff; } public Waveform process(Waveform input){ return input; } }
package interfaces.filters; public class BandPass extends Filter { double lowCutoff,highCutoff; public BandPass(double lowCutoff,double highCutoff){ this.lowCutoff = lowCutoff; this.highCutoff = highCutoff; } public Waveform process(Waveform input){ return input; } }
我们反过来找原因就会发现,主要是因为Apply.process()方法和Processor之间耦合过紧,已经超出了所需要的程度了,使得应该复用Apply.process()时复用却 用不了。
如果我们把Processor 定义为一个接口,那么耦合就会降低,就能复用Apply.process(),下面是修改的版本。
package interfaces.interfaceprocessor; public interface Processor { String name(); Object process(Object input); }
package interfaces.interfaceprocessor; import static net.mindview.util.Print.*; public class Apply { public static void process(Processor p,Object s){ print("Using Processor "+p.name()); print(p.process(s)); } }
package interfaces.interfaceprocessor; import java.util.Arrays; public abstract class StringProcessor implements Processor{ public static void main(String[] args) { Apply.process(new Upcase(), string); Apply.process(new Downcase(), string); Apply.process(new Splitter(), string); } public String name() { return getClass().getSimpleName(); } public abstract String process(Object input) ; public static String string = "disagreement with beliefs is by definition incorrct"; } class Upcase extends StringProcessor{ public String process(Object input) { return ((String)input).toUpperCase(); } } class Downcase extends StringProcessor{ public String process(Object input) { return ((String)input).toLowerCase(); } } class Splitter extends StringProcessor{ @Override public String process(Object input) { return Arrays.toString(((String)input).split(" ")); } }结果输入:
Using Processor Upcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRCT
Using Processor Downcase
disagreement with beliefs is by definition incorrct
Using Processor Splitter
[disagreement, with, beliefs, is, by, definition, incorrct]
这个时候我们还是无法Apply.process()方法在Filter上,但是我们可以引入“适配器”设计模式。适配器中代码将接受你所拥有的接口,并产生你所需要的接口,就像下面一样:
package interfaces.interfaceprocessor; import interfaces.filters.Filter; import interfaces.filters.Waveform; public class FilterAdapter implements Processor { @Override public String name() { return filter.name(); } @Override public Waveform process(Object input) { return filter.process((Waveform)input); } Filter filter ; public FilterAdapter(Filter filter){ this.filter = filter; } }
package interfaces.interfaceprocessor; import interfaces.filters.BandPass; import interfaces.filters.HighPass; import interfaces.filters.LowPass; import interfaces.filters.Waveform; public class FilterProcessor { public static void main(String[] args) { Waveform w = new Waveform(); Apply.process(new FilterAdapter(new LowPass(1.0)), w); Apply.process(new FilterAdapter(new HighPass(2.0)), w); Apply.process(new FilterAdapter(new BandPass(3.0, 4.0)), w); } }
Using Processor LowPass
Waveform 0
Using Processor HighPass
Waveform 0
Using Processor BandPass
Waveform 0
原文地址:http://blog.csdn.net/huruzun/article/details/45032879