一、描述
适配器模式就是讲一个系统的接口转换成另外一种形式,从而使原来不能直接调用的接口变得可以调用。例如我现在有一份List类型的用户名单,但是我的系统需要一份Map类型的用户名单,所以我就需要写一个继承Map类的适配器,将List类型的名单适配成Map类型的名单从而可以直接在系统只使用。
当系统需要使用一个外部的接口,而这个外部接口不满足系统需要的时候,我们需要使用适配器模式对外部接口进行封装转换为系统可以使用的类型。适配器类分为对象适配器和类适配器两种,其中对象适配器,即实现目标类的接口,依赖适配者类;而对于类适配器来说,要直接继承适配者类,并实现目标类的接口。
适配器模式主要由3部分组成:目标类、源类和适配器类。在这里目标类就是你的系统所需要的类型,而源类是指你现在拥有的但是不适合你的系统的类型,适配器类则是用于将源类转换为目标类的转换类,例如在java的I/O中,存在将字节流和字符流进行转换的适配器InputStreamReader和OutputStreamWriter,这两个类分别负责将输入字节流转换为字符流和将输出字节流转换为字符流。
二、适配器类的优缺点
优点:在系统中使用适配器模式,可以将一个系统的接口和本来不相容的另一个系统的类联系起来,在双方之间搭建一个桥梁,从而使得这两个类通过这个适配器类可以平缓过渡和融合,强调了对接口的转换。
缺点:对于类适配器来说,不能适配一个类以及它的子类;对于对象适配器来说,重新定义被适配的类的行为比较困难。因为类适配器继承了 Adaptee (被适配类),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。对象适配器不使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式,被适配器类是适配器类的成员变量。
三、源代码
1、源类:
package tong.day5_4.adapter; import java.util.ArrayList; import java.util.List; /** * 源类:返回一个List类型的内部人员列表,但是系统需要的是map类型的列表,所以需要适配器类进行转换 * @author tong * */ public class UniformFacade { //获取一个List类型的人员列表 public List<Person> getPersonList() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("张三", 35)); personList.add(new Person("李四", 30)); personList.add(new Person("王五", 25)); personList.add(new Person("赵六", 29)); return personList; } } class Person { private String name; private int age; public Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //重写toString(),打印输出person对象时按照如下格式输出 @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
2、目标类
package tong.day5_4.adapter; import java.util.HashMap; /** * 目标类:这是系统需要的类型,系统将使用这个类进行数据的输出 * @author tong * */ class ManageMap { public static void execute(HashMap map) { for (int i = 0; i < map.size(); i++) { System.out.println(map.get(i)); } } }
3、适配器类
package tong.day5_4.adapter; import java.util.HashMap; import java.util.List; /** * 适配器类:将List类型的人员表转换为Map类型的人员表 * @author tong * */ public class MapAdapter extends HashMap{ private List list; public MapAdapter(List list) { this.list = list; } public int size() { return list.size(); } public Object get(Object object) { return list.get(new Integer(object.toString()).intValue()); } }
4、客户端调用类
package tong.day5_4.adapter; //客户端测视类 public class Client { public static void main(String[] args) { //创建源类,获取源类产生的结果 UniformFacade uniformFacade = new UniformFacade(); //将源类的结果作为参数传递到适配器类中,并创建适配器对象 MapAdapter mapAdapter = new MapAdapter(uniformFacade.getPersonList()); //将适配器对象作为目标类的方法的参数,在目标类中使用适配器类的转换效果 ManageMap.execute(mapAdapter); } }
运行结果: