1.定义:将一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的类可以一起工作
2.UML
2.1类适配器模式
2.2 对象适配器
3.理论基础:里氏替换原则,继承,多态
4.涉及角色:
目标接口:客户端希望的类型
源接口/源目标:软件单位内存在的类型,实现了具体的功能
适配器:主要作用是将源目标适配成客户端希望的数据类型,复用源目标中已经实现的公能
5.优点
不管是类适配器模式还是对象适配模式都是实现了现有功能的复用,该模式下可以提高代码复用
6.缺点
1.由于适配器的存在,导致结构复杂,随着适配器的增加,后续的结构会越来越复杂
2.容易造成混淆,从代码层面分析,客户端调用的是目标接口的api,但实际上调用的却是源目标的api
7.使用场景
1.行为和数据都正确,但是类型不兼容
2.功能单元都正常,但是短时间内无法改造
类是配模式采用的是继承,属于静态的,对象是配模式采用的组合,是动态的
8.Code
8.1类适配器模式
//目标接口
//客户端希望的接口,客户端将此用该接口完成对应的操作
//1.目标接口即客户希望的接口
//2.接口定义的功能在现有的单元中已经实现,但是由于类型不兼容导致无法使用
public interface ITarget {
public int add(int a, int b);
public int subtraction(int a, int b);
public float division(float a, float b);
}
//源目标
//单位了已经实现的功能,但是接口/类型不兼容,导致现有的功能没有办法被复用
//在类的层次机构和Itarget之间不存在任何关系
public class Adaptee {
public int add(int a, int b) {
return a + b;
}
public int subtraction(int a, int b) {
return a - b;
}
}
//适配器
public class Adapter extends Adaptee implements ITarget {
@Override
public float division(float a, float b) {
if(b == 0) {
return 0;
} else {
return a / b;
}
}
}
//客户端
public class Client {
public static void main(String[] args) {
ITarget target = new Adapter();
System.out.println(target.add(2, 3));
System.out.println(target.subtraction(3, 5));
System.out.println(target.division(3, 4));
}
}
8.2对象适配器模式
//目标接口
public interface ITarget {
public int add(int a, int b);
public int subtraction(int a, int b);
public float division(float a, float b);
}
//源目标
public class Adaptee {
public int add(int a, int b, int c) {
return a + b + c;
}
public int subtraction(int a, int b, int c, float d) {
return a - b - c - (int)d;
}
}
//适配器
public class Adapter implements ITarget {
private Adaptee adaptee = new Adaptee();
@Override
public int add(int a, int b) {
return adaptee.add(a, b, 0);
}
@Override
public int subtraction(int a, int b) {
return adaptee.subtraction(a, b, 0, 0);
}
@Override
public float division(float a, float b) {
if(b == 0) {
return 0;
} else {
return a / b;
}
}
}
//客户端
public class Client {
public static void main(String[] args) {
ITarget target = new Adapter();
System.out.println(target.add(2, 3));
System.out.println(target.subtraction(3, 5));
System.out.println(target.division(3, 4));
}
}
从客户端代码可以看出,不管采用何种方式我们都没有修改客户端的代码。因为客户端以来的是抽象