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

C# 设计模式(结构型模式):外观模式

C# 设计模式(结构型模式):外观模式 (Facade Pattern)

在复杂系统中,往往会涉及到多个子系统、模块和类。这些子系统的接口和功能可能会让使用者感到困惑和复杂。在这种情况下,我们可以使用外观模式(Facade Pattern)来简化系统的操作。外观模式通过提供一个统一的接口来隐藏复杂的子系统,使得客户端可以更容易地与系统进行交互。

1. 外观模式的定义

外观模式是一种结构型设计模式,它为复杂子系统提供一个简化的接口。通过引入外观对象,客户端只需要与外观对象交互,避免直接操作复杂的子系统。外观模式能够减少客户端和多个子系统之间的耦合关系,并且提高系统的易用性。

2. 外观模式的结构

外观模式的结构主要包括以下几部分:

  • Facade(外观类):提供一个统一的接口,封装对多个子系统的调用。
  • Subsystem Classes(子系统类):多个子系统类,封装了具体的业务逻辑。外观类通过调用这些子系统的接口来实现所需的功能。
  • Client(客户端):客户端通过外观类来调用子系统,而无需直接接触子系统的复杂接口。
3. 外观模式的应用场景

外观模式适用于以下几种场景:

  • 简化接口:当一个系统或子系统变得过于复杂时,外观模式可以为其提供一个简化的接口,降低使用门槛。
  • 子系统之间解耦:外观模式可以帮助将复杂子系统的操作封装起来,减少客户端与多个子系统之间的耦合度。
  • 减少客户端对系统内部实现的依赖:客户端只需要知道如何与外观类交互,而不需要了解系统内部的实现细节。
4. C# 实现外观模式

假设我们有一个家庭影院系统,包括多个设备如音响、投影仪、灯光和蓝光播放器。每个设备都有自己独立的操作接口,客户端操作起来非常繁琐。我们可以通过外观模式来简化操作,客户端只需要与外观类交互,而不必关心各个设备的具体操作。

示例:家庭影院系统的外观模式
using System;// 子系统类:音响
public class SoundSystem
{public void On() => Console.WriteLine("Turning on the sound system...");public void Off() => Console.WriteLine("Turning off the sound system...");public void SetVolume(int volume) => Console.WriteLine($"Setting volume to {volume}.");
}// 子系统类:投影仪
public class Projector
{public void On() => Console.WriteLine("Turning on the projector...");public void Off() => Console.WriteLine("Turning off the projector...");public void SetMode() => Console.WriteLine("Setting projector mode to 1080p.");
}// 子系统类:灯光
public class Lights
{public void On() => Console.WriteLine("Turning on the lights...");public void Off() => Console.WriteLine("Turning off the lights...");public void Dim(int level) => Console.WriteLine($"Dimming lights to {level}%.");
}// 子系统类:蓝光播放器
public class BluRayPlayer
{public void On() => Console.WriteLine("Turning on the Blu-ray player...");public void Off() => Console.WriteLine("Turning off the Blu-ray player...");public void PlayMovie(string movie) => Console.WriteLine($"Playing movie: {movie}");
}// 外观类:家庭影院外观
public class HomeTheaterFacade
{private SoundSystem soundSystem;private Projector projector;private Lights lights;private BluRayPlayer bluRayPlayer;public HomeTheaterFacade(SoundSystem soundSystem, Projector projector, Lights lights, BluRayPlayer bluRayPlayer){this.soundSystem = soundSystem;this.projector = projector;this.lights = lights;this.bluRayPlayer = bluRayPlayer;}// 启动家庭影院public void WatchMovie(string movie){Console.WriteLine("Get ready to watch a movie...");lights.Dim(10);         // 调暗灯光projector.On();        // 打开投影仪projector.SetMode();   // 设置投影仪模式soundSystem.On();      // 打开音响系统soundSystem.SetVolume(20);  // 设置音量bluRayPlayer.On();     // 打开蓝光播放器bluRayPlayer.PlayMovie(movie);  // 播放电影}// 关闭家庭影院public void EndMovie(){Console.WriteLine("Shutting down the home theater...");lights.On();           // 打开灯光projector.Off();       // 关闭投影仪soundSystem.Off();     // 关闭音响bluRayPlayer.Off();    // 关闭蓝光播放器}
}// 客户端代码
class Program
{static void Main(string[] args){// 创建子系统对象SoundSystem soundSystem = new SoundSystem();Projector projector = new Projector();Lights lights = new Lights();BluRayPlayer bluRayPlayer = new BluRayPlayer();// 创建外观对象HomeTheaterFacade homeTheater = new HomeTheaterFacade(soundSystem, projector, lights, bluRayPlayer);// 客户端通过外观类与系统交互homeTheater.WatchMovie("Inception");  // 启动家庭影院,观看电影Console.WriteLine();homeTheater.EndMovie();  // 关闭家庭影院}
}
代码解析:
  • 子系统类(如 SoundSystemProjector 等)分别负责家庭影院的各个设备操作。
  • 外观类 HomeTheaterFacade 提供了一个简化的接口 WatchMovieEndMovie,客户端可以通过外观类来简化多个设备的操作,而无需直接与子系统类交互。
  • 客户端代码:客户端通过外观类 HomeTheaterFacade 来启动和关闭家庭影院系统,无需关心各个设备的详细操作。
运行结果:
Get ready to watch a movie...
Dimming lights to 10%.
Turning on the projector...
Setting projector mode to 1080p.
Turning on the sound system...
Setting volume to 20.
Turning on the Blu-ray player...
Playing movie: InceptionShutting down the home theater...
Turning on the lights...
Turning off the projector...
Turning off the sound system...
Turning off the Blu-ray player...
5. 外观模式的优缺点

优点

  • 简化客户端操作:外观模式通过提供一个统一的接口,简化了客户端与多个子系统的交互,避免了复杂的操作。
  • 解耦:外观模式将客户端与多个子系统解耦,减少了系统间的依赖关系。
  • 提高可维护性:通过引入外观类,修改子系统时不需要修改客户端代码,从而提高了系统的可维护性。

缺点

  • 可能导致过于庞大的外观类:如果系统过于复杂,外观类可能会变得非常庞大,导致维护困难。
  • 限制了子系统的灵活性:外观模式将子系统的功能封装在外观类中,可能会限制客户端直接使用子系统的某些高级功能。
6. 总结

外观模式是一种结构型设计模式,通过提供一个简化的接口,隐藏了系统中复杂的子系统细节。它帮助减少了客户端与多个子系统之间的耦合,提高了系统的可维护性和易用性。在复杂系统中,外观模式能够有效地简化用户操作,尤其适用于需要协调多个子系统工作的场景。

希望这篇文章能够帮助你理解外观模式的概念与应用!如果你有任何问题或需要进一步讨论,欢迎随时联系我!


相关文章:

C# 设计模式(结构型模式):外观模式

C# 设计模式(结构型模式):外观模式 (Facade Pattern) 在复杂系统中,往往会涉及到多个子系统、模块和类。这些子系统的接口和功能可能会让使用者感到困惑和复杂。在这种情况下,我们可以使用外观模式(Facade…...

PowerShell 常见问题解答

PowerShell 是微软开发的一种功能强大的命令行界面和脚本语言,广泛应用于系统管理和自动化任务。以下是一些使用 PowerShell 时常见的问题及其解决方法。 什么是 PowerShell? PowerShell 是基于 .NET 的命令行界面(CLI)和脚本语言…...

计算机网络 (15)宽带接入技术

前言 计算机网络宽带接入技术是指通过高速、大容量的通信信道或网络,实现用户与互联网或其他通信网络之间的高速连接。 一、宽带接入技术的定义与特点 定义:宽带接入技术是指能够传输大量数据的通信信道或网络,其传输速度通常较高&#xff0c…...

前端Python应用指南(六)构建RESTful API:使用Flask和Django实现用户认证与授权

《写给前端的python应用指南》系列: (一)快速构建 Web 服务器 - Flask vs Node.js 对比(二)深入Flask:理解Flask的应用结构与模块化设计(三)Django vs Flask:哪种框架适…...

【Unity3D】基于UGUI——简易版 UI框架

https://github.com/AMikeW/BStandShaderResources/blob/master/milk_UIFramework.unitypackage UI框架支持如下功能: 1、层级控制 2、支持面板多次打开时,隐藏前一个打开的面板,当关闭面板时,能够恢复前一个打开面板状态 3、支…...

算法排序算法

文章目录 快速排序[leetcode 215数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/)分析题解快速排序 桶排序[leetcode 347 前K个高频元素](https://leetcode.cn/problems/top-k-frequent-elements/)分析题解 快速排序 leetcode 215数组…...

第3章 总线

总线的定义 为多个部件 分时共享 公共信息传送线路。 系统之间、模块之间、芯片内部用来传递信息信号线集合。 共享 总线上可连接多个部件 各部件间相互交换信息 都可通过总线来。 分时 同一时刻 总线上只能传 一个部件信息。 采用标准总线的优点 简化系统软硬件设计 从硬件角度…...

手机实时提取SIM卡打电话的信令声音-双卡手机来电如何获取哪一个卡的来电

手机实时提取SIM卡打电话的信令声音 --双卡手机来电如何获取哪一个卡的来电 一、前言 前面的篇章《手机实时提取SIM卡打电话的信令声音-智能拨号器的双SIM卡切换方案》中,我们论述了局域网SIP坐席通过手机外呼出去时,手机中主副卡的呼叫调度策略。 但…...

共阳极LED的控制与短路问题解析

共阳极LED的控制与短路问题解析 在电子电路中,LED(发光二极管)是最常见的元件之一。LED的连接方式分为共阳极和共阴极,不同的连接方式决定了LED的控制逻辑。本文将重点讲解共阳极LED的工作原理,并解答“为什么给1不会…...

华为消费级QLC SSD来了

近日,有关消息显示,华为的消费级SSD产品线,eKitStor Xtreme 200E系列,在韩国一家在线零售商处首次公开销售,引起了业界的广泛关注。 尽管华为已经涉足服务器级别的SSD制造多年,但直到今年6月才正式推出面向…...

liunx下载gitlab

1.地址: https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 安装 postfix 并启动 yum install postfix systemctl start postfix systemctl enable postfix ssh服务启动 systemctl enable sshd systemctl start sshd开放 ssh 以及 http 服务&#xff0c…...

深度学习模型预测值集中在某一个值

深度学习模型,训练过程中,经常遇到预测的结果集中在某个值,而且在学习的过程中会变,样例如下。 主要有如下解决方案 1、更换relu ->tanh 或者其他激活函数 2、更改随机种子,估计是没有初始化好,或者调…...

Sqoop的使用

每个人的生活都是一个世界,即使最平凡的人也要为他那个世界的存在而战斗。 ——《平凡的世界》 目录 一、sqoop简介 1.1 导入流程 1.2 导出流程 二、使用sqoop 2.1 sqoop的常用参数 2.2 连接参数列表 2.3 操作hive表参数 2.4 其它参数 三、sqoop应用 - 导入…...

OpenGL ES 04 图片数据是怎么写入到对应纹理单元的

从指定路径加载图像并转换为 CGImage。获取图像的宽度和高度。创建一个 RGB 颜色空间。为图像数据分配内存。创建一个位图上下文并将图像绘制到上下文中。创建一个新的纹理对象并绑定到指定的纹理单元。指定二维纹理图像。释放分配的内存。设置纹理参数,包括放大和缩…...

C# 设计模式的六大原则(SOLID)

C# 设计模式的六大原则(SOLID) 引言 在面向对象编程中,设计模式提供了高效、可复用和可维护的代码结构。SOLID原则是软件设计中的一组重要原则,用于确保代码具有良好的可维护性、可扩展性和灵活性。SOLID是五个设计原则的首字母…...

数据库自增 id 过大导致前端时数据丢失

可以看到,前端响应参数是没有丢失精度的 但是在接受 axios 请求参数时出现了精度丢失 解决方案一:改变 axios 字符编码 axios.defaults.headers[Content-Type] application/json;charsetUTF-8; 未解决 解决方案二:手动使用 json.parse() …...

第二十六天 自然语言处理(NLP)词嵌入(Word2Vec、GloVe)

自然语言处理(NLP)中的词嵌入(Word2Vec、GloVe)技术,是NLP领域的重要组成部分,它们为词汇提供了高维空间到低维向量的映射,使得语义相似的词汇在向量空间中的距离更近。以下是对这些技术的详细解…...

MongoDB 固定集合

MongoDB 固定集合 MongoDB中的固定集合(Capped Collections)是一种具有固定大小的集合,当集合中的数据达到其最大大小时,它会自动覆盖最早的文档。这种类型的集合在MongoDB中用于实现高效的、固定大小的循环缓冲区。本文将详细介…...

数据结构9.3 - 文件基础(C++)

目录 1 打开文件字符读写关闭文件 上图源自&#xff1a;https://blog.csdn.net/LG1259156776/article/details/47035583 1 打开文件 法 1法 2ofstream file(path);ofstream file;file.open(path); #include<bits/stdc.h> using namespace std;int main() {char path[]…...

Leetcode 1254 Number of Closed Islands + Leetcode 1020 Number of Enclaves

Leetcode 1254 题意 给定一个m*n的矩阵含有0和1&#xff0c;1代表水&#xff0c;0代表陆地&#xff0c;岛屿是陆地的集合&#xff0c;如果一个岛屿和四个方向的边界相连&#xff0c;则不算封闭岛屿。求有多少个封闭的岛屿。 题目链接 https://leetcode.com/problems/number…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...

Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;Floyd 快慢指针法&#xff08;…...

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…...