0%

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

外观模式

案例

​ 使用外观模式模拟《Java 设计模式》教材 187 页第 5 题

外观

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
/**
* 外观类:主板
*
* @author Vincent
*/
public class MainFrame {

/**
* Definition: 内存 CPU 硬盘 操作系统
*/
private Memory memory;
private CPU cpu;
private HardDisk disk;
private OS os;

/**
* Constructor
*/
public MainFrame() {
this.memory = new Memory();
this.cpu = new CPU();
this.disk = new HardDisk();
this.os = new OS();
}

/**
* 按下主机的开机按钮
*/
public void on() {
memory.check();
cpu.run();
disk.read();
os.load();
}
}

子系统类

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
68
69
70
/**
* 子系统类:内存
*
* @author Vincent
*/
public class Memory {

public Memory() {
System.out.println("内存已被调用");
}

/**
* 内存自检
*/
public void check() {
System.out.println("正在自检内存!");
}
}

/**
* 子系统类:CPU
*
* @author Vincent
*/
public class CPU {

public CPU() {
System.out.println("CPU已被调用");
}

/**
* 运行CPU
*/
public void run() {
System.out.println("正在运行CPU!");
}
}

/**
* 子系统类:硬盘
*
* @author Vincent
*/
public class HardDisk {
public HardDisk() {
System.out.println("硬盘已被调用");
}

/**
* 读取硬盘
*/
public void read() {
System.out.println("正在读取硬盘!");
}
}

/**
* 子系统类:操作系统
*
* @author Vincent
*/
public class OS {
public OS() {
System.out.println("操作系统已被调用!");
}

public void load() {
System.out.println("正在载入操作系统!");
}
}

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 客户端类
*
* @author Vincent
*/
public class Client {
public static void main(String[] args) {
MainFrame mainFrame = new MainFrame();
try {
mainFrame.on();
} catch (Exception e) {
e.toString();
}
}
}

小结

角色

  • Facade(外观角色)

    在客户端中调用它的方法,以知道相关子系统的功能和责任;一般情况下,可以将客户端中发来的请求委派到相应的子系统,传递给对应的子系统对象处理

  • SubSystem(子系统角色)

    每个子系统是一个类的集合,用于实现子系统的功能,可被客户端或外观角色调用

特点

​ 对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,大大降低应用程序的复杂度,提高了程序的可维护性

优点

  • 对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使子系统更为易用

  • 实现了子系统与客户端之间的松耦合关系,使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可

  • 一个子系统的修改对其他子系统无任何影响,且子系统内部变化不会影响到外观对象

缺点

  • 不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性

  • 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则

适用环境

  • 要为访问一系列复杂的子系统提供一个简单入口

  • 客户端程序与多个子系统之间存在很大的依赖性

  • 在层次化结构中,可以使用外观模式的定义系统中每一层的入口,层与层之间不直接产生联系,而是通过外观类建立联系,降低层之间的耦合度