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

设计模式:外观模式(Facade Pattern)

文章目录

    • 一、外观模式的介绍
    • 二、实例分析
    • 三、示例代码

一、外观模式的介绍

  外观模式(Facade Pattern) 是一种结构型设计模式。它的主要思想是:为复杂子系统提供一个统一的对外接口,简化外部对系统的访问。

这样做可以:

  • 隐藏子系统的复杂性,外部只需要通过一个简单接口调用即可。
  • 降低耦合度,客户端与子系统之间不直接依赖,而是通过外观类解耦。
  • 提高可维护性,如果子系统内部有变化,只需要在外观类中调整,而不用改客户端代码。

在这里插入图片描述

外观模式的角色:

  • 外观类(Facade):对外提供统一接口,封装子系统的调用逻辑。
  • 子系统类(Subsystem):实现实际功能,可能有很多类、很多方法。
  • 客户端(Client):只与外观类交互,不直接访问子系统。

外观模式结构:
在这里插入图片描述

二、实例分析

当你通过电话给商店下达订单时, 接线员就是该商店的所有服务和部门的外观。 接线员为你提供了一个同购物系统、 支付网关和各种送货服务进行互动的简单语音接口。
在这里插入图片描述
上图中图展示了一个典型的 外观模式(Facade Pattern) 应用场景:

  • 客户(Client) → 打电话下订单
  • 接线员(Facade 外观类) → 统一对外接口
  • 内部子系统 → 仓库、支付处理、供应商、包装、送货、纳税

示例代码:

#include <iostream>
using namespace std;// 子系统类:仓库
class Warehouse {
public:void checkInventory() {cout << "仓库:检查库存\n";}
};// 子系统类:支付处理
class PaymentProcessor {
public:void processPayment() {cout << "支付处理:完成支付\n";}
};// 子系统类:供应商
class Supplier {
public:void orderFromSupplier() {cout << "供应商:下单补货\n";}
};// 子系统类:包装
class Packaging {
public:void packItem() {cout << "包装:商品已打包\n";}
};// 子系统类:送货
class Shipping {
public:void shipItem() {cout << "送货:商品已发货\n";}
};// 子系统类:纳税
class Tax {
public:void payTax() {cout << "纳税:完成订单税款缴纳\n";}
};// 外观类:接线员(对客户提供统一接口)
class ShopFacade {
private:Warehouse warehouse;PaymentProcessor payment;Supplier supplier;Packaging packaging;Shipping shipping;Tax tax;public:void placeOrder() {cout << "接线员:为您处理订单...\n";warehouse.checkInventory();supplier.orderFromSupplier();payment.processPayment();tax.payTax();packaging.packItem();shipping.shipItem();cout << "接线员:您的订单已完成!\n";}
};// 客户端
int main() {ShopFacade shop;cout << "客户:打电话下订单...\n";shop.placeOrder();return 0;
}

三、示例代码

比如我们有一个 家庭影院系统,包括:DVD 播放器、投影仪、音响等。用户只需要点击一个按钮,就能“看电影”,而不用单独操作每个设备。

#include <iostream>
using namespace std;// 子系统A:DVD播放器
class DVDPlayer {
public:void on() { cout << "DVD播放器打开\n"; }void play() { cout << "DVD开始播放\n"; }void off() { cout << "DVD播放器关闭\n"; }
};// 子系统B:投影仪
class Projector {
public:void on() { cout << "投影仪打开\n"; }void off() { cout << "投影仪关闭\n"; }
};// 子系统C:音响
class Stereo {
public:void on() { cout << "音响打开\n"; }void setVolume(int v) { cout << "音量调到 " << v << endl; }void off() { cout << "音响关闭\n"; }
};// 外观类:家庭影院
class HomeTheaterFacade {
private:DVDPlayer* dvd;Projector* projector;Stereo* stereo;
public:HomeTheaterFacade(DVDPlayer* d, Projector* p, Stereo* s): dvd(d), projector(p), stereo(s) {}void watchMovie() {cout << "准备看电影...\n";dvd->on();projector->on();stereo->on();stereo->setVolume(10);dvd->play();}void endMovie() {cout << "电影结束,关闭设备...\n";dvd->off();projector->off();stereo->off();}
};// 客户端
int main() {DVDPlayer dvd;Projector projector;Stereo stereo;HomeTheaterFacade homeTheater(&dvd, &projector, &stereo);homeTheater.watchMovie();cout << "...... 正在看电影 ......\n";homeTheater.endMovie();return 0;
}
http://www.xdnf.cn/news/19490.html

相关文章:

  • 【Proteus仿真】开关控制系列仿真——开关控制LED/拨码开关二进制计数/开关和继电器控制灯灭
  • 第3章 乱码的前世今生-字符集和比较规则
  • 常见线程池的创建方式及应用场景
  • 将基于 Spring Boot 3.0.0 的 JavaWeb 应用部署到腾讯云并配置域名
  • Iterative loop of ML development|机器学习的迭代发展
  • C#基础(②音乐播发器MCI(Media Control Interface))
  • MySQL 常用语法
  • PortSwigger靶场之Stored XSS into HTML context with nothing encoded通关秘籍
  • Spring Boot 3.x 微服务架构实战指南
  • k8s中 discovery-token和token 的区别
  • Openstack Eproxy 2025.1 安装指南
  • 基于OpenCv做照片分析应用一(Java)
  • 学习记录(二十二)--Overleaf中生成的PDF左上角1.5em问题
  • 【AI编程工具】使用Cursor快速搭建一套小型项目管理系统
  • Elasticsearch vs Solr vs OpenSearch:搜索引擎方案对比与索引设计最佳实践
  • 微服务的编程测评系统18-判题功能-Rabbitmq-用户拉黑
  • 7.2elementplus的表单布局与模式
  • 从零到一:使用anisble自动化搭建kubernetes集群
  • 代码随想录算法训练营五十三天|图论part11
  • 物理气相沉积(PVD)技术及应用现状和发展趋势
  • 【线性代数基础 | 那忘算9】基尔霍夫(拉普拉斯)矩阵 矩阵—树定理证明 [详细推导]
  • unity3d 中 R3 实际使用 安装方法
  • 7.3 el-menu
  • 螺旋曲面交线投影切线角度计算与分析
  • 深度学习数据加载实战:从 PyTorch Dataset 到食品图像分类全流程解析
  • React前端开发_Day11
  • 响应式编程框架Reactor【7】
  • Spring —— 数据源配置和注解开发
  • Uniapp 项目创建与目录结构解析
  • 网站漏洞早发现:cpolar+Web-Check安全扫描组合解决方案