⑧适配器模式
适配器模式也很简单,你笔记本上的那个拖在外面的黑盒子就是个适配器,一般你在中国能用,在日本也能用,虽然两个国家的家庭电压不同,中国是220V,日本是110V,但是这个适配器能够把这些不同的电压转换为你需要的36V电压,保证你的笔记本能正常运行。在编程的世界里面,适配器模式也是这个意思。如果有一天,两个接口,你需要把一个接口转换成另外一个接口,怎么办?继承,能解决,但是比较傻,而且还违背了OCP原则,怎么办?好在我们还要适配器模式
适配器的通用类图是这个样子的:
这个类图很容易理解,Target是一个类(接口),Adaotee是一个接口,通过Adapter把Adaptee包装成Target的一个子类(实现类),注意这里用了个名词:包装,其实这个模式也叫作包装模式,但是包装模式不止一个,还包括了装饰模式。现在举个栗子
现在我有这么一个接口:
这是我本地的UserInfo,
然后隔壁系统的接口是这样的:
现在我要把隔壁系统的IOuterUser转换成IUser,怎么转呢?
只要在中间加个适配器即可。然而这个适配器如何编写呢?
package cn.cjm.adapter;
import java.util.Map;
public class OuterUserInfo extends OuterUser implements IUserInfo{
private Map baseInfo = super.getUserBaseInfo();
private Map homeInfo = super.getUserHomeInfo();
private Map officeInfo = super.getUserOfficeInfo();
@Override
public String getUsername() {
String username = (String)this.baseInfo.get("username");
return username;
}
@Override
public String getHomeAdress() {
String homeAddress = (String)this.homeInfo.get("homeAddress");
return homeAddress;
}
@Override
public String getMobileNumber() {
String mobileNumber = (String)this.baseInfo.get("mobileNumber");
return mobileNumber;
}
@Override
public String getOfficeTelNumber() {
String officeTelNumber = (String)this.officeInfo.get("officeTelNumber");
return officeTelNumber;
}
@Override
public String getJobPosition() {
String jobPosition = (String)this.officeInfo.get("jobPosition");
return jobPosition;
}
@Override
public String getHomeTelNumber() {
String homeTelNumber = (String)this.homeInfo.get("homeTelNumber");
return homeTelNumber;
}
}
这样很轻松就完成了接口之间的转换了。
适配器模式不适合在系统设计阶段采用,没有一个系统分析师会在做详细设计的时候考虑使用适配器,这个模式使用的主要场景是扩展应用中,就像我们上面的那个例子一样,系统扩展了,不符合原有设计时才考虑通过适配器模式减少代码修改带来的风险。