Facade(外观) 结构型 对象 1
Intent_意图2
提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用
Motivation_动机3
降低访问复杂系统的内部子系统时的复杂度,简化客户与之的接口
Applicability_适用性4
1.客户不需要知道系统内部的复杂联系,整个系统只需提供一个“接待员”即可
2.定义系统的入口
Structure_结构5
Participants_参与者6
- Facade(外观) 此角色知晓相关的(一个或多个)子系统的功能和责任。
- SubSystem(子系统) 可以同时有一个或多个子系统。每个子系统都不是一个单独的类,而是一个类的集合。
Collaborations_协作7
- 客户调用Facade方法
- Facade将从客户发来的请求委派到相应的子系统去
->在正常情况下,Facade会将所有从客户发来的请求委派到相应的子系统去 - SubSystem处理Facade(或客户)发来的请求
->每个子系统 都可以被客户直接调用,或被门面调用,子系统并不知道外观的存在,对于子系统而言,外观仅仅是另一个客户而已
Comsequences_结果8
- 优点
松散了客户与子系统的耦合关系,让子系统内部的模块更容易扩展和维护
让子系统更加易用,客户不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟外观类交互
合理使用外观模式,可以更好的划分访问的层次,将对外方法集中到外观中,既方便客户使用,也可以很好的隐藏内部细节 - 缺点
不符合开放-关闭原则,如果需要改变的内容比较复杂,将会增加代码复杂度 - 用途
为复杂的模块或子系统提供外界访问模块
预防低水平人员带来的风险
Implementation/Sample Code_实现/范例代码910
Implementation
SubSystem
public class ModuleA {
public void methodA() {
System.out.println("It's method A");
}
}
public class ModuleB {
public void methodB() {
System.out.println("It's method B");
}
}
public class ModuleC {
public void methodC() {
System.out.println("It's method C");
}
}
Facade
public class Facade {
public void method() {
Module A = new ModuleA();
a.methodA();
Module B = new ModuleB();
b.methodB();
Module C = new ModuleC();
c.methodC();
}
}
Sample Code
SubSystem
public class Amplifier {
public void on() {
System.out.println("Top-O-Line Amplifier on");
}
public void setDvd(DvdPlayer dvd) {
System.out.println("Top-O-Line Amplifier setting " + dvd + " 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);
}
public void off() {
System.out.println("Top-O-Line Amplifier off");
}
}
public class CdPlayer {
}
public class DvdPlayer {
String movie;
public void on() {
System.out.println("Top-O-Line DVD Player on");
}
public void play(String movie) {
this.movie = movie;
System.out.println("Top-O-Line DVD Player playing \"" + movie + "\"");
}
public void stop() {
System.out.println("Top-O-Line DVD Player stopped \"" + movie + "\"");
}
public void eject() {
System.out.println("Top-O-Line DVD Player eject");
}
public void off() {
System.out.println("Top-O-Line DVD Player off");
}
}
public class PopcornPopper {
public void on() {
System.out.println("Popcorn Popper on");
}
public void pop() {
System.out.println("Popcorn Popper popping popcorn!");
}
public void off(){
System.out.println("Popcorn Popper off");
}
}
public class Projector {
public void on(){
System.out.println("Top-O-Line Projector on");
}
public void wideScreenMode(){
System.out.println("Top-O-Line Projector in widescreen mode (16x9 aspect ratio)");
}
public void off(){
System.out.println("Top-O-Line Projector off");
}
}
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 TheaterLights {
public void dim(int dim){
System.out.println("Theater Ceiling Lights dimming to " + dim + "%");
}
public void on(){
System.out.println("Theater Ceiling Lights on");
}
}
public class Tuner {
}
Facade
import java.util.Calendar;
public class HomeTheaterFacade {
Amplifier amp;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;
Projector projector;
TheaterLights lights;
Screen screen;
PopcornPopper popper;
HomeTheaterFacade(Amplifier amp,
Tuner tuner,
DvdPlayer dvd,
CdPlayer cd,
Projector projector,
TheaterLights lights,
Screen screen,
PopcornPopper popper) {
this.amp = amp;
this.tuner = tuner;
this.dvd = dvd;
this.cd = cd;
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 endMoive() {
System.out.println("Shutting movie theater down...");
popper.off();
lights.on();
screen.up();
projector.off();
amp.off();
dvd.stop();
dvd.eject();
dvd.off();
}
}
Demo
public class HomeTheaterTestDrive {
public static void main(String[] args) {
Amplifier amp = new Amplifier();
Tuner tuner = new Tuner();
DvdPlayer dvd = new DvdPlayer();
CdPlayer cd = new CdPlayer();
Projector projector = new Projector();
TheaterLights lights = new TheaterLights();
Screen screen = new Screen();
PopcornPopper popper = new PopcornPopper();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(amp, tuner, dvd, cd, projector, lights, screen, popper);
homeTheater.watchMovie("Raiders of the Lost Ark");
homeTheater.endMoive();
}
}
Result
Get ready to watch a movie...
Popcorn Popper on
Popcorn Popper popping popcorn!
Theater Ceiling Lights dimming to 10%
Theater Screen going down
Top-O-Line Projector on
Top-O-Line Projector in widescreen mode (16x9 aspect ratio)
Top-O-Line Amplifier on
Top-O-Line Amplifier setting DvdPlayer@1b6d3586 to Top-O-Line DVD Player
Top-O-Line Amplifier surround sound on (5 speakers, 1 subwoofer)
Top-O-Line Amplifier setting volume to 5
Top-O-Line DVD Player on
Top-O-Line DVD Player playing "Raiders of the Lost Ark"
Shutting movie theater down...
Popcorn Popper off
Theater Ceiling Lights on
Theater Screen going up
Top-O-Line Projector off
Top-O-Line Amplifier off
Top-O-Line DVD Player stopped "Raiders of the Lost Ark"
Top-O-Line DVD Player eject
Top-O-Line DVD Player off
Known Uses_已知应用11
Related Patterns_相关模式12
模式分类归属 ↩︎
意图:描述该模式的作用,以及该模式的定义 ↩︎
动机:给出了问题以及如何解决这个问题的具体场景 ↩︎
适用性:描述模式可以被应用在什么场合 ↩︎
结构:提供了图示,显示出参与此模式的类之间的关系 ↩︎
参与者:描述在此设计中所涉及到的类和对象在模式中的责任和角色 ↩︎
协作 :告诉参与者如何在此模式中合作 ↩︎
结果:描述采用此模式之后可能产生的效果,好的与不好的 ↩︎
实现:提供了在实现该模式时需要使用的技巧,以及应该小心面对的问题 ↩︎
范例代码:提供代码的片段 ↩︎
已知应用:用来描述已经在真实系统中发现的模式例子 ↩︎
相关模式:描述了此模式和其他模式之间的关系 ↩︎