0%

设计模式之结构型模式的设计与实现(一)

适配器模式

案例

​ 在现有基础上,如何扩展使其能够发出救护车灯光和声音

​ 救护车灯光和声音类已经存在,灯光类类名:AmbulanceLamp,发光方法名:lighting ();声音类类名:AmbulanceSound,发声方法名:sounding ()

目标抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 目标抽象类:汽车控制类
* @author Vincent
*/
public abstract class CarController {
public void move() {
System.out.println("玩具汽车移动!");
}

/**
* 发出声音
*/
public abstract void phonate();

/**
* 灯光闪烁
*/
public abstract void twinkle();
}

适配器类

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
* 适配器类:警车适配器
* @author Vincent
*/
public class PoliceCarAdapter extends CarController {
/**
* 定义适配者PoliceSound对象、PoliceLamp对象
*/
private PoliceSound sound;
private PoliceLamp lamp;

public PoliceCarAdapter() {
sound = new PoliceSound();
lamp = new PoliceLamp();
}

/**
* 调用适配者类PoliceSound的方法,发出警笛声音
*/
@Override
public void phonate() {
sound.alarmSound();
}

/**
* 调用适配者类PoliceLamp的方法,呈现警灯闪烁
*/
@Override
public void twinkle() {
lamp.alarmLamp();
}
}

/**
* 适配器类:救护车适配器
*
* @author Vincent
*/
public class AmbulanceCarAdapter extends CarController {
/**
* 定义适配者AmbulanceSound对象、AmbulanceLamp对象
*/
private AmbulanceSound sound;
private AmbulanceLamp lamp;

public AmbulanceCarAdapter() {
sound = new AmbulanceSound();
lamp = new AmbulanceLamp();
}

/**
* 调用适配者类AmbulanceSound的方法,发出救护车声音
*/
@Override
public void phonate() {
sound.sounding();
}

/**
* 调用适配者类AmbulanceLamp的方法,呈现救护车灯闪烁
*/
@Override
public void twinkle() {
lamp.lighting();
}
}

适配者类

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
37
38
39
40
/**
* 适配者类:警灯类
* @author Vincent
*/
public class PoliceLamp {
public void alarmLamp() {
System.out.println("呈现警灯闪烁!");
}
}

/**
* 适配者类:警笛类
* @author Vincent
*/
public class PoliceSound {
public void alarmSound() {
System.out.println("发出警笛声音!");
}
}

/**
* 适配者类:救护车灯类
* @author Vincent
*/
public class AmbulanceLamp {
public void lighting() {
System.out.println("呈现救护车灯闪烁!");
}
}

/**
* 适配者类:救护车声音类
* @author Vincent
*/
public class AmbulanceSound {
public void sounding() {
System.out.println("发出救护车声音!");
}
}

客户端

1
2
3
4
5
6
7
8
9
public class Client {
public static void main(String[] args) {
CarController car ;
car = (CarController)XMLUtil.getBean();
car.move();
car.phonate();
car.twinkle();
}
}

小结

角色

  • Target(目标抽象类)

​ 定义客户所需的接口,可以是抽象类或接口、具体类

  • Adapter(适配器类)

​ 作为转换器来调用另一个接口,从而对目标抽象类和适配者

  • Adaptee(适配者类)

​ 定义了一个已经存在的接口,这个接口需要适配,一般是一个具体类,包含客户希望使用的业务方法

特点

​ 分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高

优点

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构

  • 增加了类的透明性和复用性,提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用

  • 灵活性和扩展性非常好

  • 类适配器模式置换一些适配者的方法很方便;对象适配器模式可以把多个不同的适配者适配到同一个目标,还可以适配一个适配者的子类。

缺点

  • 类适配器模式

    • 一次最多只能适配一个适配者类,不能同时适配多个适配者
    • 适配者类不能为最终类
    • 目标抽象类只能为接口而不能为类
  • 对象适配器模式

    • 在适配器中置换适配者类的某些方法时比较麻烦

适用环境

  • 系统需要使用一些现有的类,而这些类的接口不符合系统的需要,甚至没有这些类的源代码

  • 创建一个可以重复使用的类,用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作