上一节适配器模式最后引出了外观模式,再重申一下外观模式的作用。它是一个改变接口的新模式,但是改变接口的原因是为了简化接口。它将一个或数个类的复杂的一切隐藏在背后,只显露出一个干净美好的外观。
场景描述
假设我们家里建立一套家庭影院,经过一番研究,组装了一套杀手级的系统 。内含DVD播放器、投影机、自动屏幕、环绕立体声,甚至还有爆米花机。花了好几个星期布线、挂上投影机、连接所有的装置并调试。现在,准备开始享受一部电影了,但是得先执行如下任务:
- 打开爆米花机
- 开始爆米花
- 将灯光调暗
- 放下屏幕
- 打开投影机
- 将投影机的输入切换到DVD
- 将投影机设置在宽屏模式
- 打开功放
- 将功放的输入设置为DVD
- 将功放设置为环绕立体声
- 将功放音量调到中(5)
- 打开DVD播放器
- 开始播放DVD
要看一场电影真是不容易,如果每次都这样的话,这套设备要吃灰了。更何况还不止这样:
- 看完电影后,还要把一切都关掉,怎么办?难道要反向地把这一切动作再执行一遍?
- 如果要听CD或广播,难道也这么麻烦?
- 如果决定要升级系统,可能还必须重新学习一套稍微不同的操作过程。
下面我们就来看看外观模式是如何解决这团混乱的。
代码示例
本示例涉及到的类会比较多,有爆米花机、灯、屏幕、CD机等。为了简单,我们只抽取其中两个类来演示下。假设现在流程只简化到,灯关掉,然后开启DVD机,按播放按钮,就可以了。
创建电灯,只有开灯和关灯两个方法。
123456789public class TheaterLight {public void on() {System.out.println("TheaterLight on");}public void off() {System.out.println("TheaterLight off");}}创建DVD播放器
1234567891011121314151617181920public class DvdPlayer {String movie;public void on() {System.out.println("DvdPlayer on");}public void off() {System.out.println("DvdPlayer off");}public void play(String movie) {this.movie = movie;System.out.println("DvdPlayer playing " + movie);}public void stop() {System.out.println("DvdPlayer stopped");}}创建家庭影院外观
1234567891011121314151617181920212223public class HomeTheaterFacade {private TheaterLight theaterLight;private DvdPlayer dvdPlayer;public HomeTheaterFacade(TheaterLight theaterLight, DvdPlayer dvdPlayer) {this.theaterLight = theaterLight;this.dvdPlayer = dvdPlayer;}public void watchMovie(String movie) {System.out.println("Get ready to watch a movie...");theaterLight.off();dvdPlayer.on();dvdPlayer.play(movie);}public void endMovie() {System.out.println("Shutting movie theater down...");dvdPlayer.stop();dvdPlayer.off();theaterLight.on();}}测试
12345678910public class Test {public static void main(String[] args) {TheaterLight theaterLight = new TheaterLight();DvdPlayer dvdPlayer = new DvdPlayer();HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade(theaterLight, dvdPlayer);homeTheaterFacade.watchMovie("Gone With Wind");homeTheaterFacade.endMovie();}}
从代码可以看出,这个模式也很简单,主要是逻辑上简单。其实也就是创建了一个Facade,来组合各个零件的接口,然后提供了一个更简单接口来供别人使用。我们再回顾下适配器模式,通过代码可以体会出其中的区别:适配器模式是转换接口,火鸡当鸭子用;而外观模式是通过组合封装的方式来简化接口,将流程串起来,变成一个一目了然的接口再提供出去。本章节就到这里了。