正文

一、定义

外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

要点:

  • 外观模式将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观。
  • 通过将子系统的方法封装到外观的方法中,可以达到对子系统的“一键操作”。
  • 外观模式的意图是简化接口,好让一个子系统更易于使用。
  • 外观模式将客户从组件的子系统中解耦。

二、实现步骤

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();
}
}

《Head First 设计模式》:外观模式的更多相关文章

  1. java设计模式——外观模式(门面模式)

    一. 定义与类型 定义:门面模式,提供一个统一的接口,用来访问子系统中的一群接口,门面模式定义了一个高层接口,让子系统更容易使用 类型:结构性 二. 使用场景 子系统越来越复杂,增加外观模式提供简单调 ...

  2. Java设计模式——外观模式

    JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  3. 浅谈Python设计模式 - 外观模式

    声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 外观模式 外观模式的核心在于将复杂的内部实现包装起来,只向外界提供简单的调用接口 ...

  4. 【设计模式】Java设计模式 - 外观模式

    Java设计模式 - 外观模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

  5. C#设计模式-外观模式

    在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ”门面“模 ...

  6. [Head First设计模式]生活中学设计模式——外观模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  7. JAVA 设计模式 外观模式

    用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  8. Java设计模式---外观模式

    外观模式(Facade) 外观模式的意图是:为子系统提供一个接口,便于它的使用.   解释: 简单的说,外观模式就是封装多个上层应用需要的方法,使得上层调用变得简单,为上层提供简单的接口,是设计模式中 ...

  9. 设计模式——外观模式(Facade)

    1. 概述     外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性. 例子1:一个电源总开关可以控制四盏灯 ...

  10. 设计模式 | 外观模式/门面模式(facade)

    定义: 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 结构:(书中图,侵删) 一个简洁易用的外观类 一个复杂的子系统   实例: 书中提到了理 ...

随机推荐

  1. Python自动化运维:技术与最佳实践 PDF高清完整版|网盘下载内附地址提取码|

    内容简介: <Python自动化运维:技术与最佳实践>一书在中国运维领域将有“划时代”的重要意义:一方面,这是国内第一本从纵.深和实践角度探讨Python在运维领域应用的著作:一方面本书的 ...

  2. PHP array_intersect_uassoc() 函数

    实例 比较两个数组的键名和键值(使用用户自定义函数比较键名),并返回交集: <?phpfunction myfunction($a,$b){if ($a===$b){return 0;}retu ...

  3. Python os.chflags() 方法

    概述 os.chflags() 方法用于设置路径的标记为数字标记.多个标记可以使用 OR 来组合起来.高佣联盟 www.cgewang.com 只支持在 Unix 下使用. 语法 chflags()方 ...

  4. PHP preg_match_all() 函数

    preg_match_all 函数用于执行一个全局正则表达式匹配.高佣联盟 www.cgewang.com 语法 int preg_match_all ( string $pattern , stri ...

  5. PHP str_ireplace() 函数

    实例 把字符串 "Hello world!" 中的字符 "WORLD"(不区分大小写)替换成 "Peter": <?php高佣联盟 w ...

  6. 转载——完整的ASCII码表

    完整的ASCII码表,转载自下面的博主: http://www.cnblogs.com/xmxu/archive/2012/07/10/2584032.html

  7. mit-6.828 Lab Tools

    Lab Tools 目录 Lab Tools 写在前面 GDB GNU GPL (通用公共许可证) QEMU ELF 可执行文件的格式 Verbose mode Makefile 写在前面 操作系统小 ...

  8. day12. 闭包

    一.概念 """ 如果内函数使用了外函数的局部变量, 并且外函数把内函数返回出来的过程,叫做闭包 里面的内函数是闭包函数 """ 二.基本语 ...

  9. Ef Core增加Sql方法

    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)] public class DbFunAttribute : Attri ...

  10. Tarjan算法 学习笔记

    前排提示:先学习拓扑排序,再学习Tarjan有奇效. -------------------------- Tarjan算法一般用于有向图里强连通分量的缩点. 强连通分量:有向图里能够互相到达的点的集 ...