目录
一、外观模式的定义
提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用
二、类图
三、例子
场景描述:你自己组装了一个家庭影院,内含DVD播放器、投影机、自动屏幕、环绕立体声,甚至还有爆米花机
大致类图如下:
你花费了很长时间安装、调试,现在准备享受一场电影...
挑选一张DVD影片,准备观看。忘了一件事,想看电影,必须先执行一些任务:
1、打开爆米花机
2、开始爆米花
3、将灯光调暗
4、放下屏幕
5、打开投影机
6、将投影机的输入切换到DVD
7、将投影机设置在宽屏模式
8、打开功效
...等等十几项操作
伪代码差不多这个样子:
//打开爆米花机,开始爆米花
popper.on();
popper.pop();
//灯光调暗到10%的亮度...
lights.dim(10);
//把屏幕放下
screen.down();
//带开投影机
projector.on();
projector.setInput(dvd);
//等等,设计到6个不同的类
看个电影如此繁琐复杂,怎么办?提供一个更合理的接口的外观类,将一个复杂的子系统变得更加容易使用
外观类:
public class HomeTheaterFacade {
PopcornPopper popper;
TheaterLights lights;
Projector projector;
public HomeTheaterFacade(PopcornPopper popper, TheaterLights lights,
Projector projector) {
super();
this.popper = popper;
this.lights = lights;
this.projector = projector;
}
public void watchMovie(String movie) {
System.out.println("准备观看电影:" + movie + "...");
popper.on();
popper.pop();
lights.dim(10);
projector.on();
//.....等等其他操作
}
public void endMovie(){
System.out.println("Shutting movie theater down...");
popper.off();
lights.on();
projector.off();
//.....等等其他操作
}
其他组件类-爆米花机:
public class PopcornPopper {
public void on(){
System.out.println("打开爆米花机");
}
public void pop(){
System.out.println("开始爆米花");
}
public void off(){
System.out.println("关闭爆米花机");
}
}
灯光控制:
public class TheaterLights {
public void dim(int value) {
System.out.println("灯光调暗到" + value + "%的亮度");
}
public void on() {
System.out.println("灯光调至正常模式");
}
}
投影机:
public class Projector {
public void on() {
System.out.println("打开投影机...");
}
public void off(){
System.out.println("关闭投影机...");
}
}
测试:
public class HomeTheaterTest {
public static void main(String[] args) {
PopcornPopper popper = new PopcornPopper();
TheaterLights lights = new TheaterLights();
Projector projector = new Projector();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(popper, lights,
projector);
homeTheater.watchMovie("大头儿子和小头爸爸");
homeTheater.endMovie();
}
}
结果:
准备观看电影:大头儿子和小头爸爸...
打开爆米花机
开始爆米花
灯光调暗到10%的亮度
打开投影机...
Shutting movie theater down...
关闭爆米花机
灯光调至正常模式
关闭投影机...
四、最少知识原则(墨忒尔法则):减少对象之间的交互
当你正在设计一个系统,不管是任何对象,你都要注意它所交互的类有哪些,并注意它和这些类是如何交互的。
这个原则希望,不要让太多的类耦合在一起,免得修改系统中的一部分,会影响到其他部分(牵一发而动全身)。如果许多类之间相互依赖,那么这个系统维护成本会增加,也会太复杂而不容易被其他人了解。
这个原则的缺点:包装类会变得很多;增加了复杂度和开发时间,并降低了运行时的性能。
五、适配器模式、装饰者模式、外观模式的简单比较
适配器模式将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;而外观模式将一群对象"包装"起来以简化其接口。
文章内容参考:Head First设计模式 第7章 随遇而安:适配器与外观模式