好了,通过上次的学习,我们已经知道适配器模式是如何将一个类的接口转换成另一个符合客户期望的接口。同时也知道在Java中要做到这一点,必须将一个不兼容接口的对象包装起来,变成兼容的对象。
我们现在要看一个改变接口的新模式,但是它改变接口的原因是为了简化接口。这个模式被巧妙地命名为外观模式(Facade-Pattern),之所以这么称呼,是因为它将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观。
还记得我们之前说过的命令模式中,一个遥控器能控制很多家电的过程吧。简单的开关我们都会,复杂的模式,就比较麻烦,比如看电影的步骤:
看一个电影,真的是如此繁琐。而且看完电影之后,还得过去把这些步骤都关闭。是用你的家庭影院竟然变得如此复杂!让我们看看外观模式如何解决这团混乱,好让你轻松享受。
你需要的正是一个外观:有了外观模式,通过实现一个提供更合理的接口的外观类,你可以将一个复杂的子系统变得容易使用。
好了,那接下来就到实战阶段啦。
第一步是使用组合让外观能够访问子系统中所有的组件
public class HomeTheaterFacade {
Amplifier amp;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;
Projector projector;
TheaterLights lights;
Screen screen;
PopcornPopper popper;
public HomeTheaterFacade(Amplifier amp,
Tuner tuner,
DvdPlayer dvd,
CdPlayer cd,
Projector projector,
Screen screen,
TheaterLights lights,
PopcornPopper popper) {
this.amp = amp;
this.tuner = tuner;
this.dvd = dvd;
this.cd = cd;
this.projector = projector;
this.screen = screen;
this.lights = lights;
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("Shutting movie theater down...");
popper.off();
lights.on();
screen.up();
projector.off();
amp.off();
dvd.stop();
dvd.eject();
dvd.off();
}
}
有了这个基础,后面观赏电影就变得简单了。
public class HomeTheaterTestDrive {
public static void main(String[] args) {
Amplifier amp = new Amplifier("Top-O-Line Amplifier");
Tuner tuner = new Tuner("Top-O-Line AM/FM Tuner", amp);
DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp);
CdPlayer cd = new CdPlayer("Top-O-Line CD Player", amp);
Projector projector = new Projector("Top-O-Line Projector", dvd);
TheaterLights lights = new TheaterLights("Theater Ceiling Lights");
Screen screen = new Screen("Theater Screen");
PopcornPopper popper = new PopcornPopper("Popcorn Popper");
// 根据子系统所有的组件来实例化外观
HomeTheaterFacade homeTheater =
new HomeTheaterFacade(amp, tuner, dvd, cd,
projector, screen, lights, popper);
// 使用简化的接口,并开启电影,然后关闭电影
homeTheater.watchMovie("Raiders of the Lost Ark");
homeTheater.endMovie();
}
}
就这样,我们完成了外观模式的处理。当你使用完,是不是觉得很简单了呢。
想要用外观模式,我们创建了一个接口简化而统一的类,用来包装子系统中一个或多个复杂的类。外观模式相当直接,很容易理解,这方面和许多其他的模式不太一样。但这并不会降低它的威力:外观模式允许我们让客户和子系统之间避免紧耦合。而且外观模式也帮我们遵循一个新的面向对象原则。
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
最少知识原则:只和你的密友谈话。这个原则系统我们在设计中,不要让太多的类耦合在一起,免得修改系统中的一部分,会影响到其他部分。如果许多类之间相互依赖,那么这个系统就会变成一个易碎的系统,他需要花许多成本维护,也会因为太复杂而不容易被其他人了解。
我们来做一个对比大家就知道啦
// 不采用这个原则,我们需要调用两次方法才能获取到最终的信息
public float getTemp() {
Thermometer thermometer = station.getThermometer();
return thermometer.getTemperature();
}
// 采用这个原则,我们加进一个方法,这样就可以减少我们所依赖的类的数目
public float getTemp() {
return station.getTemperature();
}
因为这次学习的内容比较简单,我就在这篇里进行总结了。
这次学习的适配器和外观,虽然篇幅不多,但是在平常写代码的过程中还是经常使用的,尤其是适配器模式,你们觉得呢?所以,这一块还得巩固好,这样对于后面编写代码,理解代码的根源很有帮助的哦。下次,我们开启模板方式模式之旅。
PS:小编在介绍适配器模式的时候,只举例说明了对象适配器。其实还有一个类适配器,但是那个是需要用到多重继承的,考虑到Java没有实际场景,这里就略过了。感兴趣的朋友可以继续深入研究下。