一.名称
二.问题(为了解决什么问题)
适配器最好在详细设计阶段不要考虑它,它不是为了解决还处在开发阶段的问题,而是解决正在服役的项目问题,是一个“补救”模式。解决兼容问题。
场景:系统扩展时,需要使用一个已有的类,但这个类又不符合系统的接口,怎么办?使用适配器模式。需要使用一个类的功能,但是该类的接口不符合使用场合要求的接口,可使用定制适配器,又或者是有一个接口定义的行为过多,则可以定义一个缺省适配器,让子类选择性的覆盖适配器的方法
三.解决方案(主要体现在uml和核心代码上)
定义:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起的两个类能够在一起工作。它的原理是增加一层。
适配器的通用代码比较简单,这里不再赘述。这里写下对象适配器和类适配器的区别:类适配器是类间继承,对象适配器是对象的合成关系,也可以说是类的关联关系,这是两者的根本区别。二者在实际项目中都会经常使用到,由于对象适配器是通过类间的关联关系进行耦合的。因此在设计时就可以做到比较灵活。在实际项目中,对象适配器使用到场景相对多一些。
四.例子
将OuterUser转化为UserInfo使用
1.类适配器模式:通过继承实现
目标类
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public interface IUserInfo {
public String getUserName();
public String getHomeAddress();
public String getMobileNumber();
public String getOfficeTelNumber();
public String getJobPosition();
public String getHomeTelNumber();
}
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public class UserInfo implements IUserInfo {
@Override
public String getUserName() {
System.out.println("这是员工的姓名");
return null;
}
@Override
public String getHomeAddress() {
System.out.println("这是员工的姓名");
return null;
}
@Override
public String getMobileNumber() {
System.out.println("这是员工的手机号码");
return null;
}
@Override
public String getOfficeTelNumber() {
System.out.println("这是员工的办公室电话号码");
return null;
}
@Override
public String getJobPosition() {
System.out.println("这是员工的职位");
return null;
}
@Override
public String getHomeTelNumber() {
System.out.println("这是员工的家庭电话");
return null;
}
}
原类
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public interface IOuterUser {
public Map getUserBaseInfo();
public Map getUserOfficeInfo();
public Map getUserHomeInfo();
}
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public class OuterUser implements IOuterUser {
/**
* 员工的基本信息
* @return
*/
@Override
public Map getUserBaseInfo() {
HashMap<String, String> map = new HashMap<>();
map.put("userName", "这个员工叫混世魔王...");
map.put("mobileNumber", "这个员工电话是...");
return map;
}
/**
* 员工的工作信息
* @return
*/
@Override
public Map getUserOfficeInfo() {
HashMap<String, String> map = new HashMap<>();
map.put("jobPosition", "这个员工的职位是...");
map.put("officeTelNumber", "这个员工的办公电话是...");
return map;
}
/**
* 员工的家庭信息
* @return
*/
@Override
public Map getUserHomeInfo() {
HashMap<String, String> map = new HashMap<>();
map.put("homeTelNumber", "这个员工的家庭电话是...");
map.put("homeAdress", "这个员工的家庭住址是...");
return map;
}
}
适配器
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public class OuterUserInfo extends OuterUser implements IUserInfo {
private Map baseInfo = super.getUserBaseInfo();
private Map<String, String> homeInfo = super.getUserHomeInfo();
private Map officeInfo = super.getUserOfficeInfo();
@Override
public String getUserName() {
return this.homeInfo.get("userName");
}
@Override
public String getHomeAddress() {
return null;
}
@Override
public String getMobileNumber() {
return null;
}
@Override
public String getOfficeTelNumber() {
return null;
}
@Override
public String getJobPosition() {
return null;
}
@Override
public String getHomeTelNumber() {
return null;
}
}
2.对象适配器模式:通过组合实现
目标类
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public interface IUserInfo {
public String getUserName();
public String getHomeAddress();
public String getMobileNumber();
public String getOfficeTelNumber();
public String getJobPosition();
public String getHomeTelNumber();
}
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public class UserInfo implements IUserInfo {
@Override
public String getUserName() {
System.out.println("这是员工的姓名");
return null;
}
@Override
public String getHomeAddress() {
System.out.println("这是员工的姓名");
return null;
}
@Override
public String getMobileNumber() {
System.out.println("这是员工的手机号码");
return null;
}
@Override
public String getOfficeTelNumber() {
System.out.println("这是员工的办公室电话号码");
return null;
}
@Override
public String getJobPosition() {
System.out.println("这是员工的职位");
return null;
}
@Override
public String getHomeTelNumber() {
System.out.println("这是员工的家庭电话");
return null;
}
}
原类
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public interface IOuterUserBaseInfo {
public Map getUserBaseInfo();
}
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public interface IOuterUserHomeInfo {
public Map getUserHomeInfo();
}
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public interface IOuterUserOfficeInfo {
public Map getUserOfficeInfo();
}
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public class OuterUserBaseInfo implements IOuterUserBaseInfo {
@Override
public Map getUserBaseInfo() {
HashMap<String, String> map = new HashMap<>();
map.put("userName", "这个员工叫混世魔王...");
map.put("mobileNumber", "这个员工电话是...");
return map;
}
}
适配器
/**
* Created by annuoaichengzhang on 16/3/26.
*/
public class OuterUserInfo implements IUserInfo{
private IOuterUserBaseInfo baseInfo = null;
private IOuterUserHomeInfo homeInfo = null;
private IOuterUserOfficeInfo officeInfo = null;
public OuterUserInfo(IOuterUserBaseInfo baseInfo, IOuterUserHomeInfo homeInfo, IOuterUserOfficeInfo officeInfo) {
this.baseInfo = baseInfo;
this.homeInfo = homeInfo;
this.officeInfo = officeInfo;
}
@Override
public String getUserName() {
return (String) this.baseInfo.getUserBaseInfo().get("userName");
}
@Override
public String getHomeAddress() {
return null;
}
@Override
public String getMobileNumber() {
return null;
}
@Override
public String getOfficeTelNumber() {
return null;
}
@Override
public String getJobPosition() {
return null;
}
@Override
public String getHomeTelNumber() {
return null;
}
}
五.效果(有啥优缺点)
优点:
1. 适配器模式可以让两个没有任何关系的类在一起运行,只要适配器这个角色能够搞定他们就成。
2. 增加了类的透明性。
3. 提高了类的复用性。
4. 灵活性非常好。假如有一天不用适配器了,删除即可,其他的代码不用修改,基本上就类似于一个灵活的构件,想用就用,不想即卸载。
常见案例
没有源码的算法库