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

来源:互联网 发布:统一台湾 知乎 编辑:程序博客网 时间:2024/05/19 03:25

假如说现在需要设计一个打印机,要适配不同的打印模式(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》

0 0