适配器模式又叫做包装模式,它可以将不符合规范的类转换为符合规范的类从而可以一起工作
就像手机充电器一样,正常安卓接口的充电器可以给安卓手机充电,但是手机型号高一些的需要使用Type-C接口的充电器,在没有充电器的情况下就可以使用转接头来连接安卓充电器,然后在给手机充电,转接头代表的就是适配器
Java案例
老板写了一个用户注册服务,在代码中使用了日志功能,老板将任务交给张王两个人来做,自己专心的写业务逻辑,定义一个日志接口,等张王二人将代码写好通过构造传进来即可:
日志接口类
public interface ILog {
void info(String msg);
void warn(String msg);
void error(String msg);
}
用户服务类
public class UserService {
private ILog log;
public UserService(ILog log) {
this.log = log;
}
// 检查注册的ID是否已存在
public boolean checkExists(String id) {
return "admin".equals(id);
}
// 注册账号的方法
public void register(String id) {
if (checkExists(id)) {
log.error(id + " 注册失败!账号已存在");
throw new RuntimeException();
}
log.warn(id + " 密码安全性过低!");
log.info(id + " 注册成功!");
}
}
结果发生了意料之外的事儿,因为当初说明任务的时候并没有进行交代,所以两个人写的日志类都不符合接口的规范:
小王的日志类
public class WangLog {
public void level1(String msg) {
System.out.println("【日志】" + msg);
}
public void level2(String msg) {
System.out.println("【警告】" + msg);
}
public void level3(String msg) {
System.err.println("【异常】" + msg);
}
}
小张的日志类
public class ZhangLog {
public void print(String msg) {
System.out.println(this.getMsg("print", msg));
}
public void warning(String msg) {
System.out.println(this.getMsg("print", msg));
}
public void fail(String msg) {
System.err.println(this.getMsg("print", msg));
}
public String getMsg(String type, String msg) {
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
return "[" + type + "] [" + time + "] ===>> " + msg;
}
}
解决方案
这个时候老板就想到了一个办法:自己写一个符合接口规范的日志类作为中转,然后在日志类中调用张王二人的日志类代码,这个中转的类就是适配器类:
小王日志类的适配器类
public class WangLogAdapter implements ILog {
private WangLog log;
public WangLogAdapter(WangLog log) {
this.log = log;
}
@Override
public void info(String msg) {
log.level1(msg);
}
@Override
public void warn(String msg) {
log.level2(msg);
}
@Override
public void error(String msg) {
log.level3(msg);
}
}
小张日志类的适配器类
public class ZhangLogAdapter implements ILog {
private ZhangLog log;
public ZhangLogAdapter(ZhangLog log) {
this.log = log;
}
@Override
public void info(String msg) {
log.print(msg);
}
@Override
public void warn(String msg) {
log.warning(msg);
}
@Override
public void error(String msg) {
log.fail(msg);
}
}
这样一来我们只需要获取到日志类实例,然后通过日志类实例获取到适配器,就可以适配到老板的代码中了:
public class ApplicationMain {
public static void main(String[] args) {
ZhangLog zhangLog = new ZhangLog();
ZhangLogAdapter zhangLogAdapter = new ZhangLogAdapter(zhangLog);
//WangLog wangLog = new WangLog();
//WangLogAdapter wangLogAdapter = new WangLogAdapter(wangLog);
UserService userService = new UserService(zhangLogAdapter);
userService.register("good");
}
}