软件设计模式系列之十二——外观模式

news2024/12/26 0:18:12

在软件设计中,经常会遇到需要与复杂子系统进行交互的情况。为了简化客户端与子系统之间的交互,提高系统的可维护性和可用性,外观模式应运而生。外观模式(Facade Pattern)是一种结构型设计模式,它提供一个统一的界面,用于访问系统中的一组相关接口,从而隐藏了系统的复杂性。在本文中,我们将深入探讨外观模式,包括其定义、举例说明、结构、实现步骤、代码实现、典型应用场景、优缺点、类似模式以及最后的小结。

1 模式的定义

外观模式是一种结构型设计模式,它提供了一个简化的接口,用于访问系统中的一组相关接口,以隐藏系统的复杂性。外观模式的主要目标是简化客户端与子系统之间的交互,同时降低了系统的耦合度。它允许客户端通过一个统一的入口点来与系统进行通信,而不需要了解系统内部的具体细节和复杂性。

2 举例说明

让我们通过几个简单的例子来说明外观模式的概念。
音响系统的例子。假设我们正在开发一个音响系统,该系统包括音响控制、CD播放器、收音机和音箱等组件。客户端希望能够简单地控制音响的各种功能,而不需要直接与每个组件进行交互。
在这里插入图片描述

智能手机的例子。智能手机的操作系统(如iOS和Android)为用户提供了一个外观,通过该外观可以轻松访问手机的各种功能,包括拨打电话、发送短信、浏览互联网、使用应用程序等。用户不需要了解手机的硬件和操作系统内部的复杂性。

家用电器的例子。一些现代家用电器,如洗衣机、洗碗机和微波炉,配备了控制面板,通过该面板用户可以选择不同的功能和设置。这些控制面板提供了一个简化的外观,使用户能够轻松操作家用电器。

汽车的驾驶控制台的例子。现代汽车的驾驶控制台包括了一系列按钮、开关和显示屏,通过这些控制界面,驾驶员可以控制汽车的各种功能,如调整座位、开启空调、切换收音机频道、导航、调整车速等。这些控制界面提供了一个简化的外观,使驾驶员能够方便地控制汽车。

3 结构

外观模式的结构包括以下主要组件:
在这里插入图片描述

外观(Facade):外观是外观模式的核心组件,它提供了一个简化的接口,用于与系统中的一组相关接口进行交互。外观负责委派请求给相应的子系统对象。

子系统(Subsystems):子系统是系统中的各个组件或模块,它们实现了系统的具体功能。外观通过与子系统协作来完成客户端的请求。

客户端(Client):客户端是使用外观模式的类或模块,它通过外观来简化与系统的交互。客户端不需要直接与子系统的具体类进行通信。

4 实现步骤

要实现外观模式,可以按照以下步骤进行操作:

定义子系统:首先,定义系统中的各个子系统,每个子系统负责实现一部分功能。

创建外观类:创建一个外观类,它包含对子系统的引用,并提供一个简化的接口,用于客户端访问系统的功能。

在外观类中委派请求:在外观类中实现方法,将客户端的请求委派给适当的子系统对象,以完成具体的操作。

客户端使用外观类:客户端通过外观类来访问系统的功能,而不需要直接与子系统的具体类进行交互。

5 代码实现

让我们使用Java代码来实现上面的音响系统的外观模式:

首先,我们创建外观类 StereoFacade:

public class StereoFacade {
    private StereoControl stereoControl;
    private CDPlayer cdPlayer;
    private Radio radio;
    private Speakers speakers;

    public StereoFacade() {
        stereoControl = new StereoControl();
        cdPlayer = new CDPlayer();
        radio = new Radio();
        speakers = new Speakers();
    }

    public void playMusic() {
        stereoControl.turnOn();
        cdPlayer.play();
        radio.tune();
        speakers.volumeUp();
    }

    public void turnOff() {
        stereoControl.turnOff();
        cdPlayer.stop();
        radio.turnOff();
        speakers.volumeDown();
    }
}

接下来,我们可以在客户端使用外观类:

public class ClientWithFacade {
    public static void main(String[] args) {
        StereoFacade stereoFacade = new StereoFacade();

        // 使用外观模式简化操作
        stereoFacade.playMusic();

        // 关闭音响
        stereoFacade.turnOff();
    }
}

通过外观模式,客户端只需与 `外观类 StereoFacade 交互,而不需要了解音响系统的具体子系统。这大大简化了客户端的代码,并提高了系统的可维护性和可用性。

6 典型应用场景

外观模式通常在以下情况下得到广泛应用:

简化复杂系统。当系统包含多个复杂的子系统或模块,并且客户端需要与这些子系统进行交互时,外观模式可以提供一个简化的接口,以减少客户端的复杂性。

解耦客户端与子系统。外观模式允许客户端与系统的具体实现解耦,使得系统的更改不会影响到客户端。

提供高层接口。外观模式可以为系统提供一个高层接口,隐藏底层组件的复杂性,使客户端更容易使用。

构建库或框架。在设计库或框架时,外观模式可以提供一个简单的接口,以便其他开发者能够轻松使用库中的功能。

7 优缺点

外观模式具有一些优点和缺点,让我们来看看:

优点:

简化接口:外观模式提供了一个简化的接口,使客户端更容易使用系统的功能。

降低耦合度:外观模式将客户端与子系统的具体实现解耦,允许系统的更改不会影响到客户端。

提高可维护性:由于外观模式隐藏了系统的复杂性,因此提高了系统的可维护性,减少了维护成本。

提供了更高层次的接口:外观模式允许为系统提供高层次的接口,有助于组织和管理复杂的代码。

缺点:

不符合开闭原则:如果系统的功能需要变化或扩展,可能需要修改外观类,这可能会违反开闭原则。

可能引入单点故障:外观模式将多个子系统封装在一个外观类中,如果外观类发生故障,整个系统可能会受到影响。

8 类似模式

与外观模式类似的模式包括以下几种,它们都涉及到简化复杂系统的接口或交互,但在目的和实现上略有不同。

适配器模式(Adapter Pattern)

适配器模式和外观模式都是结构型设计模式,它们都涉及到简化接口或交互,以便客户端能够更容易地使用系统的功能。适配器模式通常用于解决接口不兼容的问题,将一个接口转换为另一个接口。外观模式用于提供一个统一的界面,隐藏系统的复杂性,使客户端更容易使用。

代理模式(Proxy Pattern)

代理模式和外观模式都涉及到一个对象(代理或外观)充当客户端与系统之间的中介,以控制访问系统的功能。代理模式主要用于控制访问对象,通常包括延迟加载、访问控制或监控。外观模式主要用于简化客户端与系统的交互,隐藏系统的复杂性。

装饰模式(Decorator Pattern)

装饰模式和外观模式都是结构型设计模式,它们都涉及到对象的包装和功能扩展。装饰模式允许在运行时动态地添加功能,而不改变对象的接口。外观模式提供一个统一的接口,用于访问系统的一组相关接口,目的是隐藏系统的复杂性。

这些模式都与简化系统的接口或交互有关,但它们的重点和用途略有不同。在实际应用中,应根据具体问题和需求选择最合适的设计模式。

9 小结

外观模式是一种有助于简化复杂系统的结构型设计模式。它提供了一个统一的界面,用于访问系统中的一组相关接口,从而隐藏了系统的复杂性。通过外观模式,客户端可以更轻松地与系统进行交互,而不需要了解系统内部的具体细节。这种模式提高了系统的可维护性、可用性,并降低了客户端的复杂性。在设计和开发复杂系统时,外观模式可以成为一个有用的工具,以提高代码的可维护性和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1031197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

.NET超简单轻量级的HTTP请求组件Flurl

简介 Flurl是一个用于构建基于HTTP请求的C#代码的库。它的主要目的是简化和优雅地处理网络请求(只用很少的代码完成请求)。Flurl提供了一种简单的方法来构建GET、POST、PUT等类型的请求,以及处理响应和异常。它还提供了一些高级功能&#xf…

nndeploy:一款最新上线的支持多平台、简单易用、高性能的机器学习部署框架

项目地址:https://github.com/Alwaysssssss/nndeploy 介绍 nndeploy 是一款最新上线的支持多平台、高性能、简单易用的机器学习部署框架。做到一个框架就可完成多端(云、边、端)模型的高性能部署。 作为一个多平台模型部署工具,我们的框架最大的宗旨就…

Mac 上安装yt-dlp 和下载视频的操作

安装 打开终端,在终端输入 cd python的路径,然后输入pip3 install yt-dlp,如下图; 出现 如Successfully installed yt-dlp-2023.7.6 的时候,说明下载成功 下载 下载命令: yt-dlp --list-formats https…

来自华为的暴击?传高通裁员赔偿N+7 | 百能云芯

自9月20日起,高通裁员的新闻在网络上持续发酵。尽管市场充满了关于裁员细节的传言,但截至目前,高通官方尚未对此发表评论。 消息称,高通此次裁员的“重灾区”在上海的无线研发部门,甚至有传言称将直接关闭上海研发中心…

干货 | 汽车行业研发效能提升的挑战与实践案例

在 9 月 15 日的第七届 CSN 大会上,思码逸研发效能专家王艳萍受邀分享了《汽车行业研发效能提升的挑战与实践案例》。演讲包含了思码逸对多家汽车企业服务过程中总结出的行业痛点、解决方案,以及实践案例。 以下为演讲实录: 思码逸与很多知名…

基于微信小程序的校园生活管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境学生微信端的主要功能有:管理员的主要功能有:具体实现截图视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝1…

Aztec交易架构解析

1. 引言 前序博客有: Aztec的隐私抽象:在尊重EVM合约开发习惯的情况下实现智能合约隐私完全保密的以太坊交易:Aztec网络的隐私架构Aztec.nr:Aztec的隐私智能合约框架——用Noir扩展智能合约功能Account Abstraction账号抽象——…

【@胡锡进】大模型量化分析- 药明康德 603259.SH

我将使用不同的预测方法进行药明康德股票未来3天价格的预测。以下是每种方法的预测方法、详细代码和预测价格(根据提供的数据进行模拟)。 SARIMA模型预测: SARIMA(季节性自回归移动平均)模型适用于具有明显季节性的时…

PHP8中调换数组中的键值和元素值-PHP8知识详解

在php8中使用array_flip()函数可以调换数组中的键值和元素值。 在PHP8中使用array_flip()函数可以调换数组中的键值和元素值&#xff0c;示范代码如下&#xff1a; <?php$stu array("子涵"> 001,"欣怡"> 002,"梓涵">003,"晨曦…

华为OD机试 - 特异性双端队列(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#xff09;》。 刷的越多…

TikTok的全球影响:跨文化、跨国界的短视频文化

随着TikTok的崛起&#xff0c;短视频文化正在以前所未有的方式迅速传播&#xff0c;跨足了不同国家和文化的边界。本文将探讨TikTok的全球影响&#xff0c;以及它如何促进了跨文化交流和文化融合。 短视频&#xff1a;跨越语言和文化的沟通工具 TikTok的短视频格式具有独特的跨…

Downie 4下载画质的设置方法,downie 4设置下载清晰度

downie4除了能够下载网页视频外&#xff0c;大家还能根据需要自定义下载文件的分辨率&#xff0c;是Mac电脑必备的下载工具&#xff0c;Downie4下载画质如何设置&#xff1f;下面就来告诉大家具体的设置方法吧。 下载&#xff1a;Downie 4中文直装版 没修改之前&#xff0c;Dow…

SpringBoot 之配置加密

Jasypt库的使用 Jasypt是一个Java简易加密库&#xff0c;用于加密配置文件中的敏感信息&#xff0c;如数据库密码。 Jasypt库与springboot集成&#xff0c;在实际开发中非常方便。 1、引入依赖 <dependency><groupId>com.github.ulisesbocchio</groupId>&…

人工智能AI 全栈体系(四)

第一章 神经网络是如何实现的 除了全连接神经网络外&#xff0c;还有其他形式的神经网络。 此节将讲述神经网络的另一种形式&#xff1a;卷积神经网络。 四、卷积神经网络 首先我们看看全连接神经网络有什么不足。正如其名字一样&#xff0c;全连接神经网络&#xff0c;两个…

STM32F4X UCOSIII 事件集

STM32F4X UCOSIII 事件集 事件的应用场景UCOSIII事件工作机制UCOSIII事件操作函数事件创建函数事件删除函数事件发送函数事件接收函数 UCOSIII事件例程 事件在RTOS中也是一种任务间同步的机制&#xff0c;事件不能传递数据。跟信号量不同的是&#xff0c;事件可以实现一对多&am…

C++11之基础篇

C11 C11简介统一的列表初始化&#xff5b;&#xff5d;初始化std::initializer_list 声明autodecltypenullptr范围for循环 STL中一些变化arrayforward_listunderored_map&#xff0c;underored_set C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;…

HEC-RAS 1D/2D水动力与水环境模拟教程

详情点击公众号技术科研吧链接&#xff1a;HEC-RAS 1D/2D水动力与水环境模拟教程 前言 水动力与水环境模型的数值模拟是实现水资源规划、环境影响分析、防洪规划以及未来气候变化下预测和分析的主要手段。然而&#xff0c;一方面水动力和水环境模型的使用非常复杂&#xff0c…

买卖股票的最佳时机 IV

买卖股票的最佳时机 IV 力扣链接&#xff1a;188. 买卖股票的最佳时机 IV 题目描述 给你一个整数数组 prices 和一个整数 k &#xff0c;其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说&a…

动态面板案例分析

动态面板模型分析 如果在面板模型中&#xff0c;解释变量包括被解释变量的滞后值&#xff0c;此时则称之为“动态面板模型”&#xff0c;其目的是处理内生性问题。动态面板模型发展分为3个阶段&#xff0c;第1阶段是由Arellano and Bond(1991)提出的差分GMM(difference GMM)&a…

MidJourney | 教你如何做出好看的插画

企业插画主要基于关键词Corporate Flat Illustration&#xff08;企业平面插画&#xff09;构成&#xff0c;再结合常用的设计风格&#xff0c;比如孟菲斯风格&#xff0c;线条艺术&#xff0c;梦幻色调等关键词辅助&#xff0c;然后根据你产品需求&#xff0c;融合插画色彩等组…