当前位置: 首页 > news >正文

【设计模式】# 外观模式(Facade)大白话讲解!

外观模式(Facade)大白话讲解

一句话概括

就像酒店前台:你不需要知道后厨、保洁、维修等部门怎么工作,只要找前台就能搞定一切
在这里插入图片描述


现实生活比喻

场景1:酒店前台

  • 复杂子系统:客房服务、餐饮部、保洁部、维修部、结算部
  • 外观:前台接待员
  • :只需要告诉前台"我要入住",剩下的事前台帮你协调

场景2:汽车启动

  • 复杂子系统:发动机、油泵、点火系统、电池、传动系统
  • 外观:钥匙点火(或一键启动)
  • :只需要拧钥匙,不用关心各个系统如何配合工作

完整代码示例

场景:家庭影院系统

/*** 外观模式 - 家庭影院示例*/
public class Main {public static void main(String[] args) {System.out.println("=== 没有外观模式的痛苦 ===");withoutFacade();System.out.println("=== 使用外观模式的便捷 ===");withFacade();}// 没有外观模式:需要操作所有子系统public static void withoutFacade() {// 创建各个设备Amplifier amp = new Amplifier();DVDPlayer dvd = new DVDPlayer();Projector projector = new Projector();Screen screen = new Screen();Lights lights = new Lights();PopcornPopper popper = new PopcornPopper();// 手动一步步操作System.out.println("准备看电影...");popper.on();popper.pop();lights.dim(10);screen.down();projector.on();projector.setInput(dvd);projector.wideScreenMode();amp.on();amp.setDvd(dvd);amp.setSurroundSound();amp.setVolume(5);dvd.on();dvd.play("阿凡达");System.out.println("开始享受电影!\n");// 电影结束还要一个个关闭System.out.println("电影结束,关闭设备...");popper.off();lights.on();screen.up();projector.off();amp.off();dvd.stop();dvd.off();}// 使用外观模式:一键操作public static void withFacade() {HomeTheaterFacade homeTheater = new HomeTheaterFacade();// 一键观影homeTheater.watchMovie("阿凡达");// 一键结束homeTheater.endMovie();}
}/*** 复杂子系统 - 各个设备*/
class Amplifier {public void on() { System.out.println("放大器打开"); }public void off() { System.out.println("放大器关闭"); }public void setDvd(DVDPlayer dvd) { System.out.println("放大器设置DVD输入"); }public void setSurroundSound() { System.out.println("放大器设置环绕声"); }public void setVolume(int level) { System.out.println("放大器设置音量: " + level); }
}class DVDPlayer {public void on() { System.out.println("DVD播放器打开"); }public void off() { System.out.println("DVD播放器关闭"); }public void play(String movie) { System.out.println("DVD播放电影: " + movie); }public void stop() { System.out.println("DVD停止播放"); }
}class Projector {public void on() { System.out.println("投影仪打开"); }public void off() { System.out.println("投影仪关闭"); }public void setInput(DVDPlayer dvd) { System.out.println("投影仪设置DVD输入"); }public void wideScreenMode() { System.out.println("投影仪设置宽屏模式"); }
}class Screen {public void up() { System.out.println("屏幕升起"); }public void down() { System.out.println("屏幕降下"); }
}class Lights {public void on() { System.out.println("灯光打开"); }public void off() { System.out.println("灯光关闭"); }public void dim(int level) { System.out.println("灯光调暗到: " + level + "%"); }
}class PopcornPopper {public void on() { System.out.println("爆米花机打开"); }public void off() { System.out.println("爆米花机关闭"); }public void pop() { System.out.println("爆米花机开始爆米花"); }
}/*** 外观类 - 家庭影院外观*/
class HomeTheaterFacade {private Amplifier amp;private DVDPlayer dvd;private Projector projector;private Screen screen;private Lights lights;private PopcornPopper popper;public HomeTheaterFacade() {this.amp = new Amplifier();this.dvd = new DVDPlayer();this.projector = new Projector();this.screen = new Screen();this.lights = new Lights();this.popper = new PopcornPopper();}// 一键观影方法public void watchMovie(String movie) {System.out.println("准备观看电影: " + movie);popper.on();popper.pop();lights.dim(10);screen.down();projector.on();projector.setInput(dvd);projector.wideScreenMode();amp.on();amp.setDvd(dvd);amp.setSurroundSound();amp.setVolume(5);dvd.on();dvd.play(movie);System.out.println("开始享受电影!\n");}// 一键结束方法public void endMovie() {System.out.println("关闭家庭影院...");popper.off();lights.on();screen.up();projector.off();amp.off();dvd.stop();dvd.off();System.out.println("家庭影院已关闭");}// 还可以有其他便捷方法public void listenToMusic(String cd) {System.out.println("准备听音乐: " + cd);lights.on();amp.on();amp.setVolume(3);// 设置CD播放器等...System.out.println("开始欣赏音乐!");}
}

运行结果

=== 没有外观模式的痛苦 ===
准备看电影...
爆米花机打开
爆米花机开始爆米花
灯光调暗到: 10%
屏幕降下
投影仪打开
投影仪设置DVD输入
投影仪设置宽屏模式
放大器打开
放大器设置DVD输入
放大器设置环绕声
放大器设置音量: 5
DVD播放器打开
DVD播放电影: 阿凡达
开始享受电影!电影结束,关闭设备...
爆米花机关闭
灯光打开
屏幕升起
投影仪关闭
放大器关闭
DVD停止播放
DVD播放器关闭=== 使用外观模式的便捷 ===
准备观看电影: 阿凡达
爆米花机打开
爆米花机开始爆米花
灯光调暗到: 10%
屏幕降下
投影仪打开
投影仪设置DVD输入
投影仪设置宽屏模式
放大器打开
放大器设置DVD输入
放大器设置环绕声
放大器设置音量: 5
DVD播放器打开
DVD播放电影: 阿凡达
开始享受电影!关闭家庭影院...
爆米花机关闭
灯光打开
屏幕升起
投影仪关闭
放大器关闭
DVD停止播放
DVD播放器关闭
家庭影院已关闭

更实用的例子:计算机启动系统

/*** 计算机启动系统 - 外观模式示例*/
public class ComputerExample {public static void main(String[] args) {ComputerFacade computer = new ComputerFacade();// 一键开机computer.turnOn();System.out.println("\n使用计算机...\n");// 一关键机computer.turnOff();}
}/*** 复杂子系统 - 计算机各个组件*/
class CPU {public void freeze() { System.out.println("CPU冻结当前任务"); }public void jump(long position) { System.out.println("CPU跳转到引导程序位置: " + position); }public void execute() { System.out.println("CPU开始执行程序"); }
}class Memory {public void load(long position, byte[] data) { System.out.println("内存加载数据到位置: " + position); }
}class HardDrive {public byte[] read(long lba, int size) { System.out.println("硬盘读取扇区 " + lba + ", 大小: " + size + " bytes");return new byte[size];}
}class Display {public void show(String message) { System.out.println("显示器显示: " + message); }
}class PowerSupply {public void turnOn() { System.out.println("电源打开"); }public void turnOff() { System.out.println("电源关闭"); }
}/*** 外观类 - 计算机外观*/
class ComputerFacade {private CPU cpu;private Memory memory;private HardDrive hardDrive;private Display display;private PowerSupply powerSupply;// BIOS引导地址常量private static final long BOOT_ADDRESS = 0x0000;private static final long BOOT_SECTOR = 0x0010;private static final int SECTOR_SIZE = 1024;public ComputerFacade() {this.cpu = new CPU();this.memory = new Memory();this.hardDrive = new HardDrive();this.display = new Display();this.powerSupply = new PowerSupply();}// 一键开机public void turnOn() {System.out.println("=== 计算机启动过程 ===");powerSupply.turnOn();cpu.freeze();byte[] bootData = hardDrive.read(BOOT_SECTOR, SECTOR_SIZE);memory.load(BOOT_ADDRESS, bootData);cpu.jump(BOOT_ADDRESS);cpu.execute();display.show("欢迎使用计算机系统");System.out.println("计算机启动完成!");}// 一关键机public void turnOff() {System.out.println("=== 计算机关闭过程 ===");display.show("系统正在关闭...");cpu.freeze();powerSupply.turnOff();System.out.println("计算机关闭完成!");}// 重启功能public void restart() {System.out.println("=== 计算机重启 ===");turnOff();try {Thread.sleep(1000); // 等待1秒} catch (InterruptedException e) {e.printStackTrace();}turnOn();}
}

外观模式的核心结构

        Client(客户端)↓Facade(外观)┌───────┼───────┐↓       ↓       ↓
Subsystem Subsystem SubsystemA        B        C

关键特征:

  • 简化接口:为复杂子系统提供简单统一的接口
  • 解耦:客户端与子系统解耦
  • 封装:隐藏子系统的复杂性
  • 入口点:通常是访问子系统的唯一入口

适用场景(大白话版)

适合用外观模式的场景:

  1. 复杂系统简化

    // 比如框架的API、库的入口类
    // Spring的ApplicationContext、JdbcTemplate都是外观
    
  2. 分层架构

    // 服务层就是DAO层的外观
    UserService userService = new UserService();
    userService.register(user); // 内部调用多个DAO
    
  3. 第三方库封装

    // 封装复杂的第三方库,提供简单接口
    PaymentFacade payment = new PaymentFacade();
    payment.pay(amount); // 内部调用支付宝、微信等复杂API
    
  4. 遗留系统现代化

    // 为老系统提供新的简单接口
    LegacySystemFacade facade = new LegacySystemFacade();
    facade.modernOperation(); // 内部调用老系统的复杂操作
    

不适合的场景:

  1. 需要直接访问子系统:如果客户端需要直接使用子系统的特定功能
  2. 系统很简单:如果子系统本身就很简单的
  3. 需要高度灵活:如果客户端需要精细控制每个子系统组件

优缺点

优点:

  • 简化使用:客户端使用起来非常简单
  • 解耦:减少客户端与子系统的依赖
  • 提高可维护性:子系统变化时,只需要修改外观类
  • 更好的分层:明确系统边界

缺点:

  • 不够灵活:如果客户端需要特殊功能,外观可能无法满足
  • 成为上帝类:如果外观类承担太多职责,可能变得臃肿
  • 增加层数:多了一层调用,有轻微性能损失

与其它模式对比

模式目的关键区别
外观模式简化复杂系统接口提供统一入口,隐藏复杂性
适配器模式接口转换解决接口不兼容问题
中介者模式对象间通信协调多个对象间的交互
单例模式控制实例数量确保只有一个实例,外观模式通常也用单例

实际应用案例

1. Spring框架

// ApplicationContext就是各种Bean工厂、配置系统等的外观
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MyService service = context.getBean(MyService.class);

2. JDBC

// JdbcTemplate是Connection、Statement、ResultSet等的外观
JdbcTemplate template = new JdbcTemplate(dataSource);
template.query("SELECT * FROM users", rowMapper);

3. SLF4J日志门面

// SLF4J是Logback、Log4j等日志实现的外观
Logger logger = LoggerFactory.getLogger(MyClass.class);
logger.info("Hello World");

总结

外观模式就是:

  • 总指挥:协调各个部门完成复杂任务
  • 一站式服务:一个窗口解决所有问题
  • 简化界面:把复杂的操作流程封装成简单操作

核心口诀:

系统复杂接口多,
客户使用直挠头。
外观模式来封装,
简单接口解烦忧!

就像现实中的:

  • 🏨 酒店前台:协调客房、餐饮、保洁等部门
  • 🚗 汽车钥匙:一键启动复杂的发动机系统
  • 🏥 医院导诊台:指导患者到正确的科室
  • 📱 手机桌面:隐藏复杂的操作系统和硬件细节

记住:当你有一个复杂系统需要为客户端提供简单接口时,使用外观模式!

http://www.dtcms.com/a/554655.html

相关文章:

  • 做百度推广网站被攻击原创主题 wordpress
  • 网站上那些兼职网页怎么做wordpress文章发布编辑器
  • 网站内容相同算侵权吗中国建设银行网站江苏分行
  • Kubernetes 中 Service 与 Pod 详解总结
  • 网站源码下载免费源码黄页推广是什么
  • 最小调整顺序次数
  • 羽毛球赛事在哪里看seo云优化公司
  • 校园网网站建设费用网站开发支持环境
  • rdpwsx!WsxIcaStackIoControl调试记录其中Class: ff Enable: 3f
  • puppeteer配置登录页面自动化测试
  • 手机可以创建网站吗广州网站公司推荐
  • 国内知名摄影网站百度指数功能模块有哪些
  • 小程序网站建设的公司网站怎么做的支付宝接口
  • 「PPG信号处理——(3)基于PPG的脉象分析与中医诊疗研究」2025年10月31日
  • 团购网站模板下载郑州网站外包公司
  • 网站开发语言是什么网站建设需要用到什么软件有哪些
  • 红帽系、银河麒麟V10系统中成功安装部署Docker-ce引擎与Docker-Compose保姆级教程
  • 产品展示的手机网站做网站在手机显示怎么很乱
  • 班级管理网站开发江苏seo
  • 南山做网站哪家专业电商网站怎么做seo优化
  • 网站建设合同有哪些北京南站
  • 登陆建设银行wap网站类似稿定设计的软件有哪些
  • 手机网站制作优化做地方网站能赚钱吗
  • ps做网站的流程池州商城网站开发
  • 汉阳做网站多少钱商务网站开发步骤
  • 南山网站设计泰安中文网站建设电话
  • 常见Web安全漏洞全解析:从原理到防御的实战指南
  • 乾县做网站建设网站要点
  • 免费代刷网站推广企业网络营销策略
  • 函数递归求最大值