说明
外观模式可以更好的实现解耦,由外观类与客户端交互,客户端无需了解每个子系统具体的操作是什么,具体看下面的例子。
UML
代码
以Computer开机为例,Computer为外观类,Cpu、Memory、Ssd为其子系统,每个子系统有各自的启动和停止方法,有了Computer,客户端只调用Computer的开机关机方法即可,Computer会调用子系统中对应的方法,代码如下。
Cpu
/**
* @author ctl
* @date 2021/1/19
*/
public class Cpu {
void startup() {
System.out.println("cpu startup...");
}
void shutdown() {
System.out.println("cpu shutdown...");
}
}
Memory
/**
* @author ctl
* @date 2021/1/19
*/
public class Memory {
void startup() {
System.out.println("memory startup...");
}
void shutdown() {
System.out.println("memory shutdown...");
}
}
Ssd
/**
* @author ctl
* @date 2021/1/19
*/
public class Ssd {
void startup() {
System.out.println("ssd startup...");
}
void shutdown() {
System.out.println("ssd shutdown...");
}
}
Computer,客户端只调用这个类即可
/**
* @author ctl
* @date 2021/1/19
*/
public class Computer {
private Cpu cpu;
private Memory memory;
private Ssd ssd;
public Computer() {
cpu = new Cpu();
memory = new Memory();
ssd = new Ssd();
}
public void startup() {
System.out.println("开机中...");
cpu.startup();
memory.startup();
ssd.startup();
System.out.println("已开机...");
}
public void shutdown() {
System.out.println("关机中...");
cpu.shutdown();
memory.shutdown();
ssd.shutdown();
System.out.println("已关机...");
}
}
测试类
/**
* @author ctl
* @date 2021/1/19
*/
public class FacedMain {
public static void main(String[] args) {
Computer computer = new Computer();
computer.startup();
System.out.println("--------------------");
computer.shutdown();
}
}
结果
可以看到,客户端只需调用Computer的startup和shutdown方法,就可以完成对所有子系统的操作。
总结
外观模式可以使客户端只关注外观类,无需关注子系统是如何运行的,并且各个子系统间可以没有互相依赖的关系,完成解耦合。
这种模式也可以更好的完成系统分级,可以更好的控制哪些系统/方法是内部的,哪些系统/方法是对外暴露的。
乍一看外观模式和代理模式好像有点像,但实际是有区别的。
代理模式中的被代理类也是可以被访问的,只不过通过代理类将其做了扩展,客户端是知道被代理类的存在的,并且要指明给谁做代理。
外观模式中的外观类,又称门面类,是完全把子系统给包裹起来了,客户端不必关注子系统,甚至客户端可以不知道子系统的存在。