适配器模式(单接口适配)
定义
适配器模式又称为变压器模式、包装模式(Wrapper)
将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作
优缺点、应用场景
优点
- 让两个没有任何关系的类在一起运行
- 增加了类的透明性
- 提高了复用度
- 灵活性好。如果不想用就可以卸载适配器
使用场景
在一个在役的项目期望在原有接口的基础上拓展,那么适配器模式是最适合的。
即需要使用一个已有或新建的类,但这个类又不符合系统的接口,则可以使用适配器模式。
代码模拟场景
公司项目组加入外包人员,但是他们的人员管理、薪资管理等都是劳务公司管理的,需要将劳务公司的人员管理系统整合到本公司的人员管理系统
实验小结
适配器模式是一个补偿模式,一般在在役的项目进行拓展业务,需要接入其他接口数据时使用。
单接口适配:所有需要接入的数据都由一个接口发过来
UML图
内部用户接口及实现类
/**
* 员工信息接口
*/
public interface IUserInfo {
// 获取用户姓名
public String getUserName();
// 获取家庭地址
public String getHomeAddress();
// 手机号码
public String getMobileNumber();
// 办公电话(座机)
public String getOfficeTelNumber();
// 这个人的职位
public String getOccupation();
// 家庭电话
public String getHomeTelNumber();
}
/**
* 内部人员实现类
*/
public class UserInfo implements IUserInfo {
@Override
public String getUserName() {
System.out.println("姓名:Van");
return null;
}
@Override
public String getHomeAddress() {
System.out.println("地址:Los Angeles");
return null;
}
@Override
public String getMobileNumber() {
System.out.println("电话:009090");
return null;
}
@Override
public String getOfficeTelNumber() {
System.out.println("座机:9202083");
return null;
}
@Override
public String getOccupation() {
System.out.println("职位:Dungeon Master");
return null;
}
@Override
public String getHomeTelNumber() {
System.out.println("家庭电话:Boy Next Door~");
return null;
}
}
外包人员接口及实现类(即待接入的接口数据)
/**
* 外包公司的人员信息接口
*/
public interface IOuterUser {
// 基本信息
public Map<String,Object> getUserBaseInfo();
// 工作区域信息
public Map<String,Object> getUserOfficeInfo();
// 用户的家庭信息
public Map<String,Object> getUserHomeInfo();
}
/**
* 外包公司的人员实现
*/
public class OuterUser implements IOuterUser {
@Override
public Map<String, Object> getUserBaseInfo() {
Map<String,Object> baseInfo = new HashMap<>();
baseInfo.put("userName","Van DarkHomle");
baseInfo.put("mobileNumber","reoreoreoreo");
return baseInfo;
}
@Override
public Map<String, Object> getUserOfficeInfo() {
Map<String,Object> officeInfo = new HashMap<>();
officeInfo.put("homeTelNumber","18281381");
officeInfo.put("homeAddress","Los Angeles");
return officeInfo;
}
@Override
public Map<String, Object> getUserHomeInfo() {
Map<String,Object> homeInfo = new HashMap<>();
homeInfo.put("occupation","Dungeon Master");
homeInfo.put("officeTelNumber","00988");
return homeInfo;
}
}
接入中转角色
/**
* 中转角色
*/
public class OuterUserInfo extends OuterUser implements IUserInfo {
private Map<String,Object> baseInfo = super.getUserBaseInfo();
private Map<String,Object> homeInfo = super.getUserHomeInfo();
private Map<String,Object> officeInfo = super.getUserOfficeInfo();
// 员工名称
@Override
public String getUserName() {
String userName = (String) this.baseInfo.get("userName");
System.out.println(userName);
return userName;
}
// 家庭地址
@Override
public String getHomeAddress() {
String homeAddress = (String) this.homeInfo.get("homeAddress");
System.out.println(homeAddress);
return homeAddress;
}
@Override
public String getMobileNumber() {
String mobileNumber = (String) this.baseInfo.get("mobileNumber");
System.out.println(mobileNumber);
return mobileNumber;
}
@Override
public String getOfficeTelNumber() {
String officeTelNumber = (String) this.officeInfo.get("officeTelNumber");
System.out.println(officeTelNumber);
return officeTelNumber;
}
@Override
public String getOccupation() {
String occupation = (String) this.officeInfo.get("occupation");
System.out.println(occupation);
return occupation;
}
@Override
public String getHomeTelNumber() {
String homeTelNumber = (String) this.homeInfo.get("homeTelNumber");
System.out.println(homeTelNumber);
return homeTelNumber;
}
}
入口类
public class AdapterMain {
public static void main(String[] args) {
// IUserInfo userInfo = new UserInfo();
// 适配器后只需要修改实现类即可
IUserInfo userInfo = new OuterUserInfo();
userInfo.getMobileNumber();
}
}
适配器模式(多接口适配)
即待接入的数据来自不同的接口,需要先将不同接口的返回值整合到一个类中,再做适配操作
多接口适配
UML图
不同来源的接口
/**
* 外包公司人员基本信息接口
*/
public interface IOuterUserBaseInfo {
public Map<String,Object> getUserBaseInfo();
}
/**
* 外包公司人员家庭信息接口
*/
public interface IOuterUserHomeInfo {
public Map<String,Object> getUserHomeInfo();
}
/**
* 外包公司人员家庭信息接口
*/
public interface IOuterUserOfficeInfo {
public Map<String,Object> getUserOfficeInfo();
}
不同来源接口的实现类
/**
* 外包公司人员基本信息实现类
*/
public class OutUserBaseInfo implements IOuterUserBaseInfo {
@Override
public Map<String, Object> getUserBaseInfo() {
Map<String,Object> baseInfo = new HashMap<>();
baseInfo.put("userName","Van DarkHomle");
baseInfo.put("mobileNumber","reoreoreoreo");
return baseInfo;
}
}
/**
* 外包公司人员家庭信息实现
*/
public class OuterUserHomeInfo implements IOuterUserHomeInfo {
@Override
public Map<String, Object> getUserHomeInfo() {
Map<String,Object> homeInfo = new HashMap<>();
homeInfo.put("homeTelNumber","18281381");
homeInfo.put("homeAddress","Los Angeles");
return homeInfo;
}
}
/**
* 外包公司人员家庭信息实现
*/
public class OuterUserOfficeInfo implements IOuterUserOfficeInfo {
@Override
public Map<String, Object> getUserOfficeInfo() {
Map<String,Object> officeInfo = new HashMap<>();
officeInfo.put("occupation","Dungeon Master");
officeInfo.put("officeTelNumber","00988");
return officeInfo;
}
}
接口整合类
/**
* 多接口适配下的中转角色
*/
public class MoreInterfacesOuterUserInfo implements IUserInfo {
// 源目标对象
private IOuterUserBaseInfo baseInfo;
private IOuterUserHomeInfo homeInfo;
private IOuterUserOfficeInfo officeInfo;
// 数据处理
private Map<String,Object> baseMap;
private Map<String,Object> homeMap;
private Map<String,Object> officeMap;
// 通过setter方法给源对象和相应的Map对象赋值
public void setBaseInfo(IOuterUserBaseInfo baseInfo) {
this.baseInfo = baseInfo;
this.baseMap = this.baseInfo.getUserBaseInfo();
}
public void setHomeInfo(IOuterUserHomeInfo homeInfo) {
this.homeInfo = homeInfo;
this.homeMap = this.homeInfo.getUserHomeInfo();
}
public void setOfficeInfo(IOuterUserOfficeInfo officeInfo) {
this.officeInfo = officeInfo;
this.officeMap = this.officeInfo.getUserOfficeInfo();
}
@Override
public String getUserName() {
String userName = (String) this.baseMap.get("userName");
System.out.println(userName);
return userName;
}
@Override
public String getHomeAddress() {
String homeAddress = (String) this.homeMap.get("homeAddress");
System.out.println(homeAddress);
return homeAddress;
}
@Override
public String getMobileNumber() {
String mobileNumber = (String) this.baseMap.get("mobileNumber");
System.out.println(mobileNumber);
return mobileNumber;
}
@Override
public String getOfficeTelNumber() {
String officeTelNumber = (String) this.officeMap.get("officeTelNumber");
System.out.println(officeTelNumber);
return officeTelNumber;
}
@Override
public String getOccupation() {
String occupation = (String) this.officeMap.get("occupation");
System.out.println(occupation);
return occupation;
}
@Override
public String getHomeTelNumber() {
String homeTelNumber = (String) this.homeMap.get("homeTelNumber");
System.out.println(homeTelNumber);
return homeTelNumber;
}
}
入口类
/**
* 多接口下的适配器
*/
public class MoreInterfacesAdapterMain {
public static void main(String[] args) {
IOuterUserBaseInfo baseInfo = new OutUserBaseInfo();
IOuterUserHomeInfo homeInfo = new OuterUserHomeInfo();
IOuterUserOfficeInfo officeInfo = new OuterUserOfficeInfo();
MoreInterfacesOuterUserInfo adapter = new MoreInterfacesOuterUserInfo();
adapter.setBaseInfo(baseInfo);
adapter.setHomeInfo(homeInfo);
adapter.setOfficeInfo(officeInfo);
// 外包人员的信息
adapter.getUserName();
adapter.getMobileNumber();
adapter.getHomeAddress();
adapter.getHomeTelNumber();
adapter.getOccupation();
adapter.getOfficeTelNumber();
// 内部人员的信息
IUserInfo adapter1 = new UserInfo();
adapter1.getUserName();
adapter1.getMobileNumber();
adapter1.getHomeAddress();
adapter1.getHomeTelNumber();
adapter1.getOccupation();
adapter1.getOfficeTelNumber();
}
}
结果
参考书籍
秦小波《设计模式之禅》