简介
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式有两种不同的形式:
- 类适配器
- 对象适配器
类的适配器
这种适配方式,由以下几个角色组成:
- 目标(Target)角色:这就是所期待得到的接口。注意:由于这里讨论的是类适配器模式,因此目标不可以是类。
- 源(Adapee)角色:现在需要适配的接口。
- 适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。
类图
示例
假设系统存在一个现有的类UserInfo:
class UserInfo {
private Map<String, String> userBaseInfo;
public Map getUserBaseInfo() {
return userBaseInfo;
}
public void setUserBaseInfo(Map<String, String> userBaseInfo) {
this.userBaseInfo = userBaseInfo;
}
}
客户端可以通过如下方式set、get员工基本信息:
public class AdapterTest {
public static void main(String[] args) {
UserInfo oui = new UserInfo();
Map<String, String> inUserInfo = new HashMap<String, String>() {
{
put("name", "corn");
put("telNumber", "170xxxxxxxx");
}
};
oui.setUserBaseInfo(inUserInfo);
// 原有取得员工基本信息的方式
Map<String, String> outUserInfo = oui.getUserBaseInfo();
String name = outUserInfo.get("name");
String telNumber = outUserInfo.get("telNumber");
}
}
有一天,基于某种原因(也许你看着这种取数据的方式不太爽,也许是系统间数据交换的原因等),你需要按照如下接口的方式取数据:
目标员工接口:
interface UserInterface {
public String getName();
public String getTelNumber();
}
那么,现在的问题是,如何将一个既定的类转换成按照目标接口的所期望的行为形式呢?
具体怎样实现呢,可以通过如下方式进行:
class UserAdapter extends UserInfo implements UserInterface {
@Override
public String getName() {
return (String) super.getUserBaseInfo().get("name");
}
@Override
public String getTelNumber() {
return (String) super.getUserBaseInfo().get("telNumber");
}
}
从上面的UserAdapter类定义中我们发现,UserAdapter不仅实现了UserInterface接口,同时还继承了UserInfo类。在实现接口的getName()和getTelNumber()方法中,分别调用了UserInfo类中的相应方法并取得结果。由此可以满足需求。在上述定义中,按照UserInterface、UserInfo和UserAdapter在场景中的目的不同,可以具体划分成如下角色:
- UserInterface:目标角色——目标接口,系统所期待实现的目标;
- UserInfo:源角色——当前已经存在的原有的实现类,即将被适配的类;
- UserAdapter:适配器角色——将原有实现装换为目标接口的实现。
对象适配器
- 目标角色(同上)
- 源角色(同上)
- 适配器角色
类图
对象适配器使用组合代替继承,将源角色视为适配器角色的属性:
class UserAdapter implements UserInterface {
private UserInfo userInfo;
public UserAdapter() {}
public UserAdapter(UserInfo userInfo) {
this.userInfo = userInfo;
}
@Override
public String getName() {
return (String) userInfo.getUserBaseInfo().get("name");
}
@Override
public String getTelNumber() {
return (String) userInfo.getUserBaseInfo().get("telNumber");
}
}
总体而言:适配器模式是指定义一个适配器类,将一个已经存在的类,转换成目标接口所期望的行为形式。同时,一般来说,基于更多的推荐使用组合而不是继承,因此,对象适配器可能使用更多。