demo描述:现有投影仪、屏幕、DVD、爆米花,想要在家吃着爆米花看电影。如果单独调用它们的方法的话会让调用与每个类都产生关系导致调用混乱,就加了一层外观组装这些功能,通过调用外观达到调用只与外观这一个类产生关系的效果
demo代码:
四个提供功能支持的类,这里将它们做成了单例:
public class DVDPlayer {
private DVDPlayer() {
}
//单例-饿汉式
private static DVDPlayer instance = new DVDPlayer();
public static DVDPlayer getInstance() {
return instance;
}
public void on() {
System.out.println("dvd on");
}
public void off() {
System.out.println("dvd off");
}
public void play() {
System.out.println("dvd is playing");
}
public void pause() {
System.out.println("dvd pause...");
}
}
public class Popcorn {
private Popcorn (){}
private static Popcorn instance = new Popcorn();
public static Popcorn getInstance() {
return instance;
}
public void on() {
System.out.println("popcorn on");
}
public void off() {
System.out.println("popcorn ff");
}
public void poping() {
System.out.println("popcorn is poping");
}
}
public class Projector {
private Projector(){}
private static Projector instance = new Projector();
public static Projector getInstance() {
return instance;
}
public void on() {
System.out.println("Projector on");
}
public void off() {
System.out.println("Projector ff");
}
public void poping() {
System.out.println("Projector is Projector");
}
}
public class Screen {
private Screen(){}
private static Screen instance = new Screen();
public static Screen getInstance() {
return instance;
}
public void up() {
System.out.println("Screen up");
}
public void down() {
System.out.println("Screen down");
}
}
外观,调用与支持间的隔层,整合业务:
public class HomeTheaterFacade {
private DVDPlayer dvdPlayer;
private Popcorn popcorn;
private Projector projector;
private Screen screen;
public HomeTheaterFacade() {
this.dvdPlayer = DVDPlayer.getInstance();
this.popcorn = Popcorn.getInstance();
this.projector = Projector.getInstance();
this.screen = Screen.getInstance();
}
//各种流程
public void ready() {
popcorn.on();
popcorn.poping();
screen.down();
projector.on();
screen.up();
dvdPlayer.on();
}
public void play(){
dvdPlayer.play();
}
public void pause(){
dvdPlayer.pause();
}
public void end(){
popcorn.off();
screen.up();
projector.off();
screen.down();
dvdPlayer.off();
}
}
客户端:
public class Client {
public static void main(String[] args) {
HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
homeTheaterFacade.ready();
homeTheaterFacade.play();
}
}
demo类图:
类图分析:下边4个类提供功能上的支持,调用者调用的时候会根据自己的逻辑、顺序调用4个类中不同的方法来完成自己的业务,会与多个类产生关联,不方便自己的扩展,加一层外观后让外观去完成自己的任务,自己调用外观,这样就只与外观类产生关联,方便扩展。
适用场景:业务流程较复杂、涉及的类多时可以加一层外观,隔离支持类与调用者
总结:外观模式屏蔽了支持层的细节;外观类没有自己的东西只做方法的整合,通过聚合调用支持类的方法。
没有什么问题不是加一层不能解决的。