适配器模式理解和使用

内容参考 https://www.jianshu.com/p/9d0575311214 、慕课网

是什么?作用?

定义一个包装类(Adapter),用于包装不兼容接口的对象(Adaptee)

  • 优点: 可以让接口不兼容而不能一起工作的那些类可以在一起工作
  • 缺点: 过多的使用适配器,会让系统非常零乱,不易整体进行把握

理解

分为两个模式

  • 类的适配器模式、
  • 对象的适配器模式

使用实例

实例概况 - 类的适配器模式 - 继承的方式

  • 背景:买了一个进口笔记本电脑
  • 冲突:笔记本电脑需要的三项电源,和只提供的二项电源冲突
  • 解决方案:设置一个适配器二项充电口转化为三项充电口

步骤1: 创建Target接口(期待得到的插头):能输出三项供电

1
2
3
4
5
6
7
8
/**
* 插头提供三项供电 (target)*/
public interface ThreePower {
/**
* 三项供电
*/
void powerByThree();
}

步骤2: 创建源类(现有的插头)

1
2
3
4
5
6
7
8
9
/**
* 插头 提供二项供电 Adaptee
*/
public class TwoPower {

public void powerByTwo() {
System.out.println("提供二项供电");
}
}

步骤3:创建适配器类(Adapter)

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 二项转三项的适配器 继承的方式 类
*/
public class TwoToThreeAdapter2 extends TwoPower implements ThreePower {


@Override
public void powerByThree() {
System.out.println("借助继承适配器转化二项电");
this.powerByTwo();
}
}

步骤4:定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标, 让笔记本能够用使用三项电

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 笔记本电脑 这是使用组合模式的-适配器模式
*/
public class NoteBook {

/**
* 期望的三项供电接口
*/
private ThreePower threePower;

public NoteBook(ThreePower threePower) {
this.threePower = threePower;
}


public static void main(String[] args) {
// ================ 继承方式的适配器使用 类适配器 ========================
ThreePower threePower1 = new TwoToThreeAdapter2();
NoteBook noteBook1 = new NoteBook(threePower1);
noteBook1.recharge();
noteBook1.work();
}

public void work() {
System.out.println("笔记本电脑开始工作!");
}

public void recharge() {
// 使用三项充电
threePower.powerByThree();
}
}

实例概况 - 对象的适配器模式 - 组合的方式 (感觉用的更多)

与类的适配器模式相同,对象的适配器模式也是把适配的类的API转换成为目标类的API。

步骤1: 创建Target接口(期待得到的插头):能输出三项供电

1
// 参照如上

步骤2: 创建源类(现有的插头)

1
// 参照如上

步骤3: 创建适配器类(Adapter)(不使用继承而是委派)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 二项转三项的适配器 组合的方式 对象适配器
*/
public class TwoToThreeAdapter implements ThreePower{

private TwoPower twoPower;

public TwoToThreeAdapter(TwoPower twoPower) {
this.twoPower = twoPower;
}

@Override
public void powerByThree() {
System.out.println("借助组合适配器转化二项电");
twoPower.powerByTwo();
}
}

步骤4:定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* 笔记本电脑 这是使用组合模式的-适配器模式
*/
public class NoteBook {

/**
* 期望的三项供电接口
*/
private ThreePower threePower;

public NoteBook(ThreePower threePower) {
this.threePower = threePower;
}

public static void main(String[] args) {

// ============================ 组合方式的适配器使用 对象适配器 =====================================
// 现在只有二项供电
TwoPower twoPower = new TwoPower();
ThreePower threePower = new TwoToThreeAdapter(twoPower);
NoteBook noteBook = new NoteBook(threePower);
// 1. 充电
noteBook.recharge();
// 2. 工作
noteBook.work();
}

public void work() {
System.out.println("笔记本电脑开始工作!");
}

public void recharge() {
// 使用三项充电
threePower.powerByThree();
}
}

总结

  • 第二种对象的适配器模式在angular里面注入组件时用的应该是适配器模式, 使用属性来组合,耦合性第一点

  • 第一种类的适配器模式解耦合更好,因为要继承

适配器好处

  • 重用, 复用的现存的类, 解决了现存类和复用环境要不一致的问题
  • 低耦合, 无需修改原有代码(遵循开闭原则)