概述
一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作。
属于结构型设计模式。
生活场景:
两脚转三角;手机充电接口;显示器接口
使用场景
1、已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况。
2、适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案。
类似于,亡羊补牢,打补丁;
适配器模式的优点
1、能提高类的透明性和复用,现有的类复用但不需要改变。
2、目标类和适配器类解耦,提高程序的扩展性。
3、在很多业务场景中符合开闭原则。
适配器模式的缺点
1、适配器编写过程需要全面考虑,可能会增加系统的复杂性。
2、增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。
类图1-1:
截图:
目标对象target与Adaptee 没关系,现在增加了一个 Adapter,使得用户能够访问Target的行为也能访问Adaptee的功能;
举个栗子#类适配
public class Adaptee {
public int specificRequest() {
return 220;
}
}
public interface Target {
int request();
}
// 俺是适配器
public class Adapter extends Adaptee implements Target {
@Override
public int request() {
return super.specificRequest() / 10;
}
}
public class CalssAdapterDemo {
public static void main(String[] args) {
Target adapter = new Adapter();
int result = adapter.request();
System.out.println(result);
}
}
// demo2
// 默认输出电压 220伏
public class AC220 {
public int outputAC220V(){
int output = 220;
System.out.println("输出电压" + output + "V");
return output;
}
}
// 新的是要5伏电,这个行为
public interface DC5 {
int output5V();
}
// 将5伏电进行转换
public class PowerAdapter extends AC220 implements DC5{
@Override
public int output5V() {
int adapterInput = super.outputAC220V();
int adapterOutput = adapterInput / 44;
System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V");
return adapterOutput;
}
}
public class AdapterClassDemo2 {
// 缺点:不符合最少知道原则
// -> 提出了对象适配器解决
public static void main(String[] args) {
DC5 adapter = new PowerAdapter();
adapter.output5V();
}
}
举个栗子#对象适配
public class AC220 {
public int outputAC220V(){
int output = 220;
System.out.println("输出电压" + output + "V");
return output;
}
}
public interface DC5 {
int output5V();
}
// 不通过继承现在有的,通过注入
public class PowerAdapter implements DC5 {
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
@Override
public int output5V() {
int adapterInput = ac220.outputAC220V();
int adapterOutput = adapterInput / 44;
System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V");
return adapterOutput;
}
}
public class ObjectAdapterDemo {
public static void main(String[] args) {
// 用AC就AC,满足最少知道原则
// 接口适配器 ,关注系统,解决接口方法过多,接口适配器,只实现我们需要的接口;
DC5 adapter = new PowerAdapter(new AC220());
adapter.output5V();
}
}
举个栗子#接口适配
public class AC220 {
public int outputAC220V(){
int output = 220;
System.out.println("输出电压" + output + "V");
return output;
}
}
public interface DC {
int output5V();
int output12V();
int output24V();
int output36V();
}
public class PowerAdapter implements DC {
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
@Override
public int output5V() {
int adapterInput = ac220.outputAC220V();
int adapterOutput = adapterInput / 44;
System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V");
return adapterOutput;
}
@Override
public int output12V() {
return 0;
}
@Override
public int output24V() {
return 0;
}
@Override
public int output36V() {
return 0;
}
}
public class InterfaceAdapterDemo {
public static void main(String[] args) {
// 缺点:不符合单一职责,开闭职责
DC adapter = new PowerAdapter(new AC220());
adapter.output5V();
adapter.output12V();
}
}
举个栗子#登录demo
public class PassportService {
/**
* 注册方法
*
* @param username
* @param password
* @return
*/
public ResultMsg regist(String username, String password) {
System.out.println("regist :" + username + "," + password);
return null;
}
/**
* 登录的方法
*
* @param username
* @param password
* @return
*/
public ResultMsg login(String username, String password) {
System.out.println("login :" + username + "," + password);
return null;
}
}
public interface IPassportForThird {
ResultMsg loginForQQ(String openId);
ResultMsg loginForWechat(String openId);
ResultMsg loginForToken(String token);
ResultMsg loginForTelphone(String phone,String code);
}
public class ResultMsg {
}
public class PassportForThirdAdapter extends PassportService implements IPassportForThird {
@Override
public ResultMsg loginForQQ(String openId) {
return loginForRegist(openId, null);
}
@Override
public ResultMsg loginForWechat(String openId) {
return loginForRegist(openId, null);
}
@Override
public ResultMsg loginForToken(String token) {
return loginForRegist(token, null);
}
@Override
public ResultMsg loginForTelphone(String phone, String code) {
return loginForRegist(phone, null);
}
private ResultMsg loginForRegist(String username, String password) {
if (null == password) {
password = "THIRD_EMPTY";
}
super.regist(username, password);
return super.login(username, password);
}
}
public class PassportDemo1 {
public static void main(String[] args) {
PassportForThirdAdapter adapter = new PassportForThirdAdapter();
adapter.login("ddsd", "dad");
adapter.loginForQQ("asdsa");
adapter.loginForWechat("adaasd");
}
}
spring中实现
SpringAOP handlerAdapter前后判断;
Spring MVC dispatcher,reqeustHandler的使用;
1