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