适配器模式 一个简单场景

最近在重构旧的代码,感觉代码异常的糟糕,连配置文件都是在java代码中写死的。

这个不是本文的重点,本文主要通过一个例子来慢慢分析适配器的模式,对适配器模式可以先看下

http://haolloyin.blog.51cto.com/1177454/346128这个文章,写的不错,但是感觉还是有点抽象。

我们这里以java编程思想(第4版)的15章的泛型中提到的适配来讲解。(部分代码做了修改,并加了点自己的理解)

首先有一个Fill的类。

public class Fill {
    //初始化size个classToken放到collection里
    public static <T> void fill(Collection<T> collection,
           Class<? extends T> classToken, int size) {
        for(int i = 0; i < size; i++){
            collection.add(classToken.newInstance());
        }
    }
}

 再有一个比较简单的队列。

public class SimpleQueue<T> implements Iterable<T> {
    private LinkedList<T> storage = new LinkedList<T>();//LinkedList 也是一个simple队列
    public void add(T t) {storage.offer(t);}
    public T get() {return storage.poll();}
    public Iterator<T> iterator(){
        return storage.iterator();
    }
}

写个测试用例:

public class FillTest{
    public static void main(String[] args){
        List<String> list1 = new ArrayList<>();
        Fill.fill(list1,String.class,2);
        SimpleQueue<String> queue1 = new SimpleQueue<>();
        //下面的代码将会编译失败
        Fill.fill(queue1,String.class,2);
    }
}

 问题出来了,Fill类竟然不能处理SimpleQueue,我这里面也有add方法啊。是哪出问题了,对了,就是这个Fill类有问题,由于Fill设计的不合理,导致无法处理除Collection以外的类了。

 

那我们重新定义Fill类,这里命名为Fill2

//定义一个可add的接口
interface Addable<T> {void add(T t);}


public class Fill2{
    public static <T> void fill(Addable<T> addable,Class<? extends T> classToken, int size){
        for(int i= 0;i < size ; i++){
            try{
                addadle.add(clasToken.newInstance());
            }catch(Exception e){
                 throw new RuntimeException(e);
            }
        }
    }
}

这里我们定义了Fill2,它可以支持所有实现Addable接口的类,但是Collection没有实现Addable接口啊,那怎么办?就需要一个适配类了。

class AddableCollectionAdapter<T> implements Addable<T>{
    private Collection<T> c;
    //一个参数为Collection的构造器
    public AddableCollectionAdapter(Collection<T> c){
        this.c = c;
    }
    public void add(T item){
         c.add(item);
    }
}

这里由于Collection类是java内置的接口,我们不易使用类适配器(两个接口都有add()方法,Colleciont还有大量别的方法),最好使用对象适配器。 同理我们也可以为Simplequeue添加一个适配类,但Simplequeue是自己定义,使用类适配器会更好点:

class AddableSipleQueue<T> extends SimpleQueue<T> Addable<T> {
    public void add(T item ){super.add(item);}
}

 下面我们测试下:

class Fill2Test {
    public static void main(String[] args){
        List<String> list = new ArrayList<>;
        Fill2.fill(new AddableColletionAdapter(list),String.class,2);
        Addable<String> queue = new AddableSimpleQueue<>();
        Fill2.fill(queue,String.class,2);
    }
}

 写到这里再抛出个问题,如果还是用Fill类,那能不能写SimpleQueue适配类来适应Fill里的Collection?

总结下:适配有2种方式:类适配器和对象适配器。

              适配器一般用在前期设计不合理导致的,需要后期的修改,一般少用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值