适配器模式模式

泰国插座用的是两孔的(欧洲标准),可以买个多功能转换插头(适配器),这样就可以用了。

image-20190831120051424

基本介绍

  • 适配器模式(Adapter Pattern):将某个类的接口转化为目标客户期望的另一个接口表示,主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。
  • 适配器属于结构型模式。
  • 主要分为三类:类适配器模式对象适配器模式接口适配器模式
  • 原型模式中包含如下要素:
    • Source: 被适配者,需要被适配的类、接口、对象,简称src。
    • Adapter:适配器
    • Desitination:目标,最终需要输出,det,即Target。
    • Director:指挥者,构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要的作用,1:隔离了客户与对象的生产过程,2:负责控制产品对象的生产过程。
    • image-20190831120119284

需求引入

  • 以生活中充电器举例子来讲适配器,充电器本身相当于Adaper,220V交流电相当于src(被适配者),我们的目标des是5V直流电)

类适配器

思路

image-20190831135515150

代码

Voltage220V

1
2
3
4
5
6
7
public class Voltage220V {
public int outPut220V(){
int src = 220;
System.out.println("电压="+src+"V");
return 220;
}
}

Voltage5V

1
2
3
public interface Voltage5V {
public int outPut5V();
}

VoltageAdapter

1
2
3
4
5
6
7
8
9
10
11
public class VoltageAdapter extends Voltage220V implements Voltage5V{
@Override
public int outPut5V() {
//获取220V电压
int srcV = outPut220V();
//转换成5V
int dstV = srcV/44;
System.out.println("电压转为5V");
return dstV;
}
}

Phone

1
2
3
4
5
6
7
8
9
public class Phone {
public void charging(Voltage5V voltage5V){
if(voltage5V.outPut5V() == 5){
System.out.println("电压为5V,可以充电");
}else if(voltage5V.outPut5V()>5){
System.out.println("电压大于5V,不可以充电");
}
}
}

Client

1
2
3
4
5
6
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}

优缺点

  • 客Java是单继承机制,所以类适配器需要继承src类这一点算是一个缺点,因为这要求dst必须是接口,有一定局限性。
  • src类的方法在Adpater中会暴露出来,也增加了使用的成本。
  • Adapter由于其继承了src类,所以它可以根据需要重写src类的方法,使得Adapter的灵活性增强。

对象配器

思路

  • 基本思路和类的适配器模式相同,只是将Adapter类做修改,不是继承src类,二十持有src类的实例,已解决兼容性问题。即:只有src类,实现dst类接口,完成src-》dst的适配。
  • 根据”合成复用原则“,在系统中尽量使关联关系(聚合)来代替继承关系。
  • 对象适配器模式是适配器模式常用的一种

image-20190831141104841

代码

VoltageAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class VoltageAdapter implements Voltage5V{
private Voltage220V voltage220V;

public VoltageAdapter2() {
}

public VoltageAdapter2(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}

@Override
public int outPut5V() {
//获取220V电压
int srcV = voltage220V.outPut220V();
//转换成5V
int dstV = srcV/44;
System.out.println("电压转为5V");
return dstV;
}
}

Client

1
2
3
4
5
6
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter2(new Voltage220V()));
}
}

优缺点

  • 对象适配器和类适配器其实算一种思想,只不过是实现的方式不同。
  • 组合服用原则,使用组合代替继承,所以它解决了类适配器必须要继承src的局限性问题,也不再要求dst必须是接口。
  • 使用成本更低,更灵活。

接口适配器

思路

  • 一些书籍称为”适配器模式(Default Adapter Pattern)或缺适配器模式。
  • 核心思想:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每一个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择地覆盖父类的某些方法来实现需求。比如:Spring中WebMvcConfigurer类。
  • 试用于一个接口不想使用其他所有的方法的情况。

image-20190831155110810

代码

Interface4

1
2
3
4
5
6
7
8
9
10
/**
* @author kongliufeng
*/
public interface Interface4 {
void operation1();
void operation2();
void operation3();
void operation4();
}

AbsAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class AbsAdapter implements Interface4{
@Override
public void operation1() {

}

@Override
public void operation2() {

}

@Override
public void operation3() {

}

@Override
public void operation4() {

}
}

VoltageAdapter

1
2
3
4
5
6
7
8
9
10
11
public class VoltageAdapter extends Voltage220V implements Voltage5V{
@Override
public int outPut5V() {
//获取220V电压
int srcV = outPut220V();
//转换成5V
int dstV = srcV/44;
System.out.println("电压转为5V");
return dstV;
}
}

Client

1
2
3
4
5
6
7
8
9
10
public class Client {
public static void main(String[] args) {
AbsAdapter absAdapter = new AbsAdapter(){
@Override
public void operation1() {
System.out.println("operation1 方法使用");
}
};
}
}