正文
一、定义
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
要点:
- 外观模式将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观。
- 通过将子系统的方法封装到外观的方法中,可以达到对子系统的“一键操作”。
- 外观模式的意图是简化接口,好让一个子系统更易于使用。
- 外观模式将客户从组件的子系统中解耦。
二、实现步骤
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(); } }
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于