`

设计模式之Adapter(适配器)

 
阅读更多

 

注释:以下资料都是个人从网上收集起来的,会注明来源地址

 

一、定义与介绍

 

       1、定义

 

定义为将一个类的接口变换成客户端所期待的一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

      

       2、对象适配器

 

继承自需要被适配的类,并且实现目标类的接口。
       3、类适配器
将需要被适配的类的对象作为自己私有属性,实现目标类的接口
 
       4、要点
a. 适配器模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
b. 适配器模式有对象适配器和类适配器两种形式的实现结构,但是类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
      
        5、优点
可以使两个没有关系的类在一起运行;
增加了类的透明性;
提高了类的复用;
灵活性好。

      6、说明

适配器模式是一个补偿模式,或者说是一个补救模式,通常来解决接口不相容的问题。一般来说最初设计的时候不会考虑这个模式,只是在有了新的业务需求时,这个是一个补救的模式。

 

二、使用

    

       1、如何使用?
      

       实现Adapter方式,其实"think in Java"的"类再生"一节中已经提到,有两种方式:组合(composition)和继承(inheritance).

       假设我们要打桩,有两种类:方形桩 圆形桩.

 

      public class SquarePeg{
    public void insert(String str){
    System.out.println("SquarePeg insert():"+str);
   }

      }

       public class RoundPeg{
      public void insertIntohole(String msg){
    System.out.println("RoundPeg insertIntoHole():"+msg);
            }
      }

 

 

        现在有一个应用,需要既打方形桩,又打圆形桩.那么我们需要将这两个没有关系的类综合应用.假设RoundPeg我们没有源代码,或源代码我们不想修改,那么我们使用Adapter来实现这个应用:

 

public class PegAdapter extends SquarePeg{
  private RoundPeg roundPeg;

  public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

  public void insert(String str){super.insert(str); roundPeg.insertIntoHole(str);}

}

 

 

        在上面代码中,RoundPeg属于Adaptee,是被适配者.PegAdapter是Adapter,将Adaptee(被适配者RoundPeg)和Target(目标SquarePeg)进行适配.实际上这是将组合方法(composition)和继承(inheritance)方法综合运用.

         PegAdapter首先继承SquarePeg,然后使用new的组合生成对象方式,生成RoundPeg的对象roundPeg,再重载父类insert()方法。从这里,你也了解使用new生成对象和使用extends继承生成对象的不同,前者无需对原来的类修改,甚至无需要知道其内部结构和源代码.

如果你有些Java使用的经验,已经发现,这种模式经常使用。

         2、进一步使用
         上面的PegAdapter是继承了SquarePeg,如果我们需要两边继承,即继承SquarePeg 又继承RoundPeg,因为Java中不允许多继承,但是我们可以实现(implements)两个接口(interface)

 

public interface IRoundPeg{
  public void insertIntoHole(String msg);

}

public interface ISquarePeg{
  public void insert(String str);

}

        

           下面是新的RoundPeg 和SquarePeg, 除了实现接口这一区别,和上面的没什么区别。

 

public class SquarePeg implements ISquarePeg{
  public void insert(String str){
    System.out.println("SquarePeg insert():"+str);
  }

}

public class RoundPeg implements IRoundPeg{
  public void insertIntohole(String msg){
    System.out.println("RoundPeg insertIntoHole():"+msg);
  }
}

 

 

         下面是新的PegAdapter,叫做two-way adapter:

 

public class PegAdapter implements IRoundPeg,ISquarePeg{

  private RoundPeg roundPeg;
  private SquarePeg squarePeg;

  // 构造方法
  public PegAdapter(RoundPeg peg){this.roundPeg=peg;}
  // 构造方法
  public PegAdapter(SquarePeg peg)(this.squarePeg=peg;)

  public void insert(String str){ roundPeg.insertIntoHole(str);}

}

 

   还有一种叫Pluggable Adapters,可以动态的获取几个adapters中一个。使用Reflection技术,可以动态的发现类中的Public方法。

 

      例子:

MapAdapter.java

package com.hysec.utils.jaxb;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.annotation.adapters.XmlAdapter;


public class MapAdapter extends XmlAdapter<MapEntity[], Map> {
    
    @Override
    public MapEntity[] marshal(Map map) throws Exception {
        // TODO Auto-generated method stub
        MapEntity[] list = new MapEntity[map.size()];
        Set keyset = map.keySet();
        int index =0;
        for(Iterator itor=keyset.iterator();itor.hasNext();){
            MapEntity item = new MapEntity();
            item.key = itor.next();
            item.value = map.get(item.key);
            list[index++] = item;            
        }
        return list;
    }

    @Override
    public Map unmarshal(MapEntity[] list) throws Exception {
        // TODO Auto-generated method stub
        Map map = new HashMap();
        for(int i=0;i<list.length;i++){
            MapEntity item = list[i];
            map.put(item.key, item.value);
        }
        
        return map;
        
    }

}

 

 来源:《Adapter_百度百科》《设计模式之Adapter(适配器)》《CXF+JAXB处理复杂的数据之XMLAdapter》

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics