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

外观模式及运用场景

外观模式(Facade Pattern)是一种结构性设计模式,它为复杂子系统提供一个统一的接口,从而简化与这些子系统的交互。通过外观模式,客户端可以更轻松地使用复杂系统,而不必了解其内部实现。接下来,我们将通过示例代码详细讲解外观模式,并探讨它的应用场景。

外观模式示例代码

在这个示例中,我们将创建一个简单的音响系统。这个系统包括多个子系统,如 DVD 播放器、CD 播放器和音响设备。我们会为这个复杂系统提供一个外观类,以简化用户的操作。

示例代码

// DVD 播放器子系统
class DVDPlayer {public void on() {System.out.println("DVD 播放器开机");}public void play() {System.out.println("DVD 播放中...");}public void off() {System.out.println("DVD 播放器关机");}
}// CD 播放器子系统
class CDPlayer {public void on() {System.out.println("CD 播放器开机");}public void play() {System.out.println("CD 播放中...");}public void off() {System.out.println("CD 播放器关机");}
}// 音响设备子系统
class SoundSystem {public void on() {System.out.println("音响设备开机");}public void setVolume(int level) {System.out.println("音量设置为 " + level);}public void off() {System.out.println("音响设备关机");}
}// 外观类
class HomeTheaterFacade {private DVDPlayer dvdPlayer;private CDPlayer cdPlayer;private SoundSystem soundSystem;public HomeTheaterFacade() {dvdPlayer = new DVDPlayer();cdPlayer = new CDPlayer();soundSystem = new SoundSystem();}public void watchMovie() {soundSystem.on();soundSystem.setVolume(10);dvdPlayer.on();dvdPlayer.play();}public void listenToCD() {soundSystem.on();soundSystem.setVolume(5);cdPlayer.on();cdPlayer.play();}public void turnOff() {dvdPlayer.off();cdPlayer.off();soundSystem.off();}
}// 客户端代码
public class Main {public static void main(String[] args) {HomeTheaterFacade homeTheater = new HomeTheaterFacade();homeTheater.watchMovie();homeTheater.listenToCD();homeTheater.turnOff();}
}

外观模式的运用场景

外观模式可以在多个实际应用场景中发挥重要作用。以下是几个常见的运用场景及其相应的代码示例。

1. 简化复杂系统

在电商系统中,用户需要完成商品购买,这可能涉及订单、商品、支付和会员等多个子系统。我们可以通过外观类来简化用户的操作。

示例代码
// 商品子系统
class ProductService {public void listProducts() {System.out.println("列出所有商品");}
}// 订单子系统
class OrderService {public void createOrder(String product) {System.out.println("创建订单,商品: " + product);}
}// 支付子系统
class PaymentService {public void processPayment(String orderId) {System.out.println("处理订单支付,订单ID: " + orderId);}
}// 电商外观类
class ECommerceFacade {private ProductService productService;private OrderService orderService;private PaymentService paymentService;public ECommerceFacade() {productService = new ProductService();orderService = new OrderService();paymentService = new PaymentService();}public void purchaseProduct(String product) {productService.listProducts();orderService.createOrder(product);paymentService.processPayment("12345");}
}// 客户端代码
public class Main {public static void main(String[] args) {ECommerceFacade facade = new ECommerceFacade();facade.purchaseProduct("手机");}
}

2. 减少客户端处理的系统数量

在 Web 应用中,客户端可能需要处理多个系统的调用,如数据库、业务对象等。通过创建一个 DAO 层作为门面,可以简化这些操作。

示例代码
// 模拟数据库操作
class Database {public void connect() {System.out.println("连接数据库");}public void disconnect() {System.out.println("关闭数据库连接");}public String fetchData() {return "数据记录";}
}// 业务对象
class BusinessModel {private String data;public BusinessModel(String data) {this.data = data;}public void display() {System.out.println("业务数据: " + data);}
}// DAO层
class DataAccessFacade {private Database database;public DataAccessFacade() {database = new Database();}public BusinessModel getBusinessModel() {database.connect();String data = database.fetchData();database.disconnect();return new BusinessModel(data);}
}// 客户端代码
public class Main {public static void main(String[] args) {DataAccessFacade dataAccess = new DataAccessFacade();BusinessModel model = dataAccess.getBusinessModel();model.display();}
}

3. 让一个系统为多个系统工作

线程池是外观模式的另一个典型应用,它为系统提供统一的线程管理接口,使得线程的创建和使用变得简单。

示例代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;// 线程池外观
class ThreadPoolFacade {private ExecutorService executorService;public ThreadPoolFacade(int poolSize) {executorService = Executors.newFixedThreadPool(poolSize);}public void executeTask(Runnable task) {executorService.execute(task);}public void shutdown() {executorService.shutdown();}
}// 客户端代码
public class Main {public static void main(String[] args) {ThreadPoolFacade threadPool = new ThreadPoolFacade(5);for (int i = 0; i < 10; i++) {final int taskId = i;threadPool.executeTask(() -> {System.out.println("执行任务 " + taskId);});}threadPool.shutdown();}
}

总结

外观模式通过提供一个统一的接口,简化了复杂系统的使用,减少了客户端与多个子系统之间的直接交互。在电商系统、数据库访问和线程管理等场景中,外观模式都能有效提高系统的可维护性和可读性。合理运用外观模式,可以显著提升开发效率和用户体验。

相关文章:

外观模式及运用场景

外观模式&#xff08;Facade Pattern&#xff09;是一种结构性设计模式&#xff0c;它为复杂子系统提供一个统一的接口&#xff0c;从而简化与这些子系统的交互。通过外观模式&#xff0c;客户端可以更轻松地使用复杂系统&#xff0c;而不必了解其内部实现。接下来&#xff0c;…...

PyQt5实战——多脚本集合包,UI以及工程布局(二)

个人博客&#xff1a;苏三有春的博客 系列往期&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; 布局 2.1 UI页面布局 整体框架分为分为三个部分&#xff0c;垂直分布。 第一个部分为功能选择按钮&#xff08;如UTF-8转换&#…...

Python 数据结构对比:列表与数组的选择指南

文章目录 &#x1f4af;前言&#x1f4af;Python中的列表&#xff08;list&#xff09;和数组&#xff08;array&#xff09;的详细对比1. 数据类型的灵活性2. 性能与效率3. 功能与操作4. 使用场景5. 数据结构选择的考量6. 实际应用案例7. 结论 &#x1f4af;小结 &#x1f4af…...

gem5运行简单RISC-V全系统模拟

简单记录gem5中运行最简单的RISC-V Full System Simulation的过程 首先是编译RISC-V和m5term&#xff0c;这部分不多写了&#xff0c;官网均有对应教程。 之后直接使用官方在configs/example/gem5_library目录下的riscv-fs.py 运行如下命令 ./build/RISCV/gem5.opt configs/…...

洛谷 P1195 口袋的天空

自用。 题目传送门&#xff1a;口袋的天空 - 洛谷 题解&#xff1a;Inori_333 参考题解&#xff1a;题解 P1195 【口袋的天空】 - 洛谷专栏 /*P1195 口袋的天空https://www.luogu.com.cn/problem/P11952024/11/03 submit:inori333 */#include <iostream> #include &…...

ffmpeg视频滤镜:膨胀操作-dilation

滤镜介绍 dilation 官网链接 > FFmpeg Filters Documentation 膨胀滤镜会使图片变的更亮&#xff0c;会让细节别的更明显。膨胀也是形态学中的一种操作&#xff0c;在opencv中也有响应的算子。此外膨胀结合此前腐蚀操作&#xff0c;可以构成开闭操作。 开操作是先腐蚀…...

3.3 windows,ReactOS系统中页面的换出----2,结构体PHYSICAL_PAGE

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…...

lvgl

lvgl 目录 lvgl Lvgl移植到STM32 -- 1、下载LVGL源码 -- 2、将必要文件复制到工程目录 -- 3、修改配置文件 将lvgl与底层屏幕结合到一块 -- lvgl也需要有定时器,专门给自己做了一个函数,告诉lvgl经过了多长时间(ms(毫秒)级别) 编写代码 lvgl的中文教程手册网站…...

【django】RESTful API 设计指南

目录 一、协议 二、域名 三、版本&#xff08;Versioning&#xff09; 四、路径&#xff08;Endpoint&#xff09; 五、HTTP动词 5.1 CRUD操作&#xff1a; 5.2 其他动词&#xff1a; 六、过滤信息&#xff08;Filtering&#xff09; 七、状态码&#xff08;Status Co…...

提升大数据量分页查询性能:深分页优化全解

前言 在处理数据量逐渐增大的数据库表时&#xff0c;优化查询性能是一个常见的挑战。朋友们可能会建议说&#xff0c;创建索引不就能解决问题了吗&#xff1f;然而&#xff0c;当数据量达到相当规模时&#xff0c;简单的索引可能不足以应对所有情况。这时&#xff0c;可能会有…...

WPF 实现冒泡排序可视化

WPF 实现冒泡排序可视化 实现冒泡排序代码就不过多讲解&#xff0c;主要是实现动画效果思路&#xff0c;本demo使用MVVM模式编写&#xff0c;读者可自行参考部分核心代码&#xff0c;即可实现如视频所示效果。 对于新手了解算法相关知识应该有些许帮助&#xff0c;至于其它类型…...

Claude 3.5 新功能 支持对 100 页的PDF 图像、图表和图形进行可视化分析

Claude 3.5 Sonnet发布PDF图像预览新功能&#xff0c;允许用户分析长度不超过100页的PDF中的视觉内容。 此功能使用户能够轻松上传文档并提取信息&#xff0c;特别适用于包含图表、图形和其他视觉元素的研究论文和技术文档。 视觉PDF分析&#xff1a;用户现在可以从包含各种视觉…...

正式开源:从 Greenplum 到 Cloudberry 迁移工具 cbcopy 发布

Cloudberry Database 作为 Greenplum 衍生版本和首选开源替代&#xff0c;由 Greenplum 原始团队成员创建&#xff0c;与 Greenplum 保持原生兼容&#xff0c;并能实现无缝迁移&#xff0c;且具备更新的 PostgreSQL 内核和更丰富的功能。GitHub: https://github.com/cloudberry…...

Python如何读写文件?

1. 文件读取 &#xff08;1&#xff09;使用open()函数打开文件 基本语法是file_object open(file_name, mode)&#xff0c;其中file_name是要打开的文件的名称&#xff08;包括路径&#xff0c;如果文件不在当前目录下&#xff09;&#xff0c;mode是打开文件的模式。例如&a…...

100种算法【Python版】第38篇——Boyer-Moore算法

本文目录 1 算法说明2 算法示例3 python代码1 算法说明 Boyer-Moore算法由Robert S. Boyer和J. Strother Moore于1977年提出,旨在提高字符串匹配的效率。该算法在寻找固定模式的过程中,利用模式本身的信息,优化搜索过程,特别适合长文本中的模式查找。 算法原理 Boyer-Moo…...

贪心算法---java---黑马

贪心算法 1)Greedy algorithm 称之为贪心算法或者贪婪算法&#xff0c;核心思想是 将寻找最优解的问题分为若干个步骤每一步骤都采用贪心原则&#xff0c;选取当前最优解因为未考虑所有可能&#xff0c;局部最优的堆叠不一定得到最终解最优 贪心算法例子 Dijkstra while …...

程序员的减压秘籍:高效与健康的平衡艺术

引言 在当今竞争激烈的科技行业中&#xff0c;程序员常常面临着极高的精神集中要求和持续的创新压力。这种工作性质让许多程序员在追求高效和创新的过程中&#xff0c;感到精疲力竭&#xff0c;面临身心健康的挑战。因此&#xff0c;找到有效的方法来缓解工作压力&#xff0c;…...

2024 年 QEMU 峰会纪要

2024 年 QEMU 峰会已于 10 月 31 日在 KVM 论坛召开&#xff0c;这是一个仅对项目中最活跃的维护者和子维护者开放的邀请会议。 出席者&#xff1a; Dan Berrang Cdric Le Goater Kevin Wolf Michael S. Tsirkin Stefan Hajnoczi Philippe Mathieu-Daud Markus Armbruster Th…...

C++/list

目录 1.list的介绍 2.list的使用 2.1list的构造 2.2list iterator的使用 2.3list capacity 2.4list element access 2.5list modifers 2.6list的迭代器失效 3.list的模拟实现 4.list与vector的对比 欢迎 1.list的介绍 list的文档介绍 cplusplus.com/reference/list/li…...

刘艳兵-DBA015-对于属于默认undo撤销表空间的数据文件的丢失,哪条语句是正确的?

对于属于默认undo撤销表空间的数据文件的丢失&#xff0c;哪条语句是正确的&#xff1f; A 所有未提交的交易都将丢失。 B 数据库实例中止。 C 数据库处于MOUNT状态&#xff0c;需要恢复才能打开。 D 数据库保持打开状态以供查询&#xff0c;但除具有SYSDBA特权的用…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...