正文
一、定义
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
要点:
外观模式将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观。
通过将子系统的方法封装到外观的方法中,可以达到对子系统的“一键操作”。
外观模式的意图是简化接口,好让一个子系统更易于使用。
外观模式将客户从组件的子系统中解耦。
二、实现步骤
1、创建子系统组件类
(1)子系统组件A
/*** 子系统组件A*/public class ComponentA {public void action() {System.out.println("ComponentA action...");}}
(2)子系统组件B
/*** 子系统组件B*/public class ComponentB {public void action() {System.out.println("ComponentB action...");}}
(3)子系统组件C
/*** 子系统组件C*/public class ComponentC {public void action() {System.out.println("ComponentC action...");}}
2、创建外观类
外观类的方法封装了子系统组件的一系列方法。这样,客户就可以通过外观类的方法,来一次性调用一系列子系统组件的方法。而不是一个个去调用子系统组件的方法。
/*** 外观类*/public class Facade {ComponentA componentA;ComponentB componentB;ComponentC componentC;public Facade(ComponentA componentA,ComponentB componentB,ComponentC componentC) {this.componentA = componentA;this.componentB = componentB;this.componentC = componentC;}/*** 通过外观类,请求子系统组件*/public void request() {componentA.action();componentB.action();componentC.action();}}
3、使用外观访问子系统组件
public class Test {public static void main(String[] args) {// 子系统组件ComponentA componentA = new ComponentA();ComponentB componentB = new ComponentB();ComponentC componentC = new ComponentC();// 外观类Facade facade = new Facade(componentA, componentB, componentC);facade.request();}}
三、举个栗子
1、背景
假设你打算建立自己的家庭影院,通过一番研究比较,你组装了一套杀手级的系统,内含 DVD 播放器、投影机、自动屏幕、环绕立体声,甚至还有爆米花机。
你花了几个星期布线、挂上投影机、连接所有的装置并进行微调。现在你打算播放一部 DVD 影片放松一下。
但是你发现,在看电影前,必须先进行一系列操作:打开爆米花机 -> 开始爆米花 -> 将灯光调暗 -> 放下屏幕 -> 打开投影机 -> 将投影机的输入切换到 DVD -> 将投影机设置在宽屏模式 -> 打开功放 -> 将功放的输入设置为 DVD -> 将功放设置为环绕立体声 -> 将功放音量调到中(5) -> 打开 DVD 播放器 -> 开始播放 DVD。
不仅如此,看完电影后,你还要把一切都关掉。使用你的家庭影院竟变得如此复杂!于是你决定升级你的系统……
2、实现
使用外观模式将看电影相关的一系列操作,封装到外观的 watchMovie() 方法中。这样一来,要看电影的时候,只需要进行一个“看电影”的操作就行了。同理,可将看完电影相关的一系列操作,封装到 endMovie() 方法中。
(1)创建家庭影院子系统组件
/*** 功放*/public class Amplifier {/*** 打开功放*/public void on() {System.out.println("Top-O-Line Amplifier on");}/*** 关闭功放*/public void off() {System.out.println("Top-O-Line Amplifier off");}/*** 设置DVD*/public void setDvd(DvdPlayer dvd) {System.out.println("Top-O-Line Amplifier setting DVD player to Top-O-Line DVD Player");}/*** 设置为环绕立体声*/public void setSurroundSound() {System.out.println("Top-O-Line Amplifier surround sound on (5 speakers, 1 subwoofer)");}/*** 调节音量*/public void setVolume(int volume) {System.out.println("Top-O-Line Amplifier setting volume to " + volume);}}
/*** DVD播放器*/public class DvdPlayer {/*** 打开DVD播放器*/public void on() {System.out.println("Top-O-Line DVD Player on");}/*** 关闭DVD播放器*/public void off() {System.out.println("Top-O-Line DVD Player off");}/*** 播放DVD*/public void play(String movie) {System.out.println("Top-O-Line DVD Player playing “" + movie + "”");}/*** 停止播放DVD*/public void stop() {System.out.println("Top-O-Line DVD Player stop");}/*** 弹出DVD*/public void eject() {System.out.println("Top-O-Line DVD Player eject");}}
/*** 投影仪*/public class Projector {/*** 打开投影仪*/public void on() {System.out.println("Top-O-Line Projector on");}/*** 关闭投影仪*/public void off() {System.out.println("Top-O-Line Projector off");}/*** 设为宽屏模式*/public void wideScreenMode() {System.out.println("Top-O-Line Projector in widescreen mode (16x9 aspect ratio)");}}
/*** 影院灯光*/public class TheaterLights {/*** 打开灯光*/public void on() {System.out.println("Theater Ceiling Lights on");}/*** 调暗灯光*/public void dim(int level) {System.out.println("Theater Ceiling Lights dimming to " + level + "%");}}
/*** 屏幕*/public class Screen {/*** 放下屏幕*/public void down() {System.out.println("Theater Screen going down");}/*** 升起屏幕*/public void up() {System.out.println("Theater Screen going up");}}
/*** 爆米花机*/public class PopcornPopper {/*** 打开爆米花机*/public void on() {System.out.println("Popcorn Popper on");}/*** 关闭爆米花机*/public void off() {System.out.println("Popcorn Popper off");}/*** 开始爆米花*/public void pop() {System.out.println("Popcorn Popper popping popcorn!");}}
(2)创建家庭影院外观
/*** 家庭影院外观*/public class HomeTheaterFacade {Amplifier amp;DvdPlayer dvd;Projector projector;TheaterLights lights;Screen screen;PopcornPopper popper;public HomeTheaterFacade(Amplifier amp,DvdPlayer dvd,Projector projector,TheaterLights lights,Screen screen,PopcornPopper popper) {this.amp = amp;this.dvd = dvd;this.projector = projector;this.lights = lights;this.screen = screen;this.popper = popper;}/*** 看电影*/public void watchMovie(String movie) {System.out.println("Get ready to watch a movie...");popper.on();popper.pop();lights.dim(10);screen.down();projector.on();projector.wideScreenMode();amp.on();amp.setDvd(dvd);amp.setSurroundSound();amp.setVolume(5);dvd.on();dvd.play(movie);}/*** 看完电影*/public void endMovie() {System.out.println("Shuting movie theater down...");popper.off();lights.on();screen.up();projector.off();amp.off();dvd.stop();dvd.eject();dvd.off();}}
(3)使用家庭影院外观观看电影
public class Test {public static void main(String[] args) {// 子系统组件Amplifier amp = new Amplifier();DvdPlayer dvd = new DvdPlayer();Projector projector = new Projector();TheaterLights lights = new TheaterLights();Screen screen = new Screen();PopcornPopper popper = new PopcornPopper();// 家庭影院外观HomeTheaterFacade homeTheater = new HomeTheaterFacade(amp, dvd, projector, lights, screen, popper);// 看电影homeTheater.watchMovie("Raiders of the Lost Ark");// 看完电影homeTheater.endMovie();}}




