【软考】设计模式之外观模式

news2024/11/20 23:14:58

目录

          • 1. 说明
          • 2. 应用场景
          • 3. 结构图
          • 4. 构成
          • 5. 适用性
          • 6. 优点
          • 7. 缺点
          • 8. java示例

1. 说明
  • 1.为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
  • 2.Facade Pattern。
  • 3.是一种结构型设计模式,提供了一种简化的接口,用于访问
  • 4.这种模式的主要目标是简化客户端与子系统之间的交互,同时降低系统的耦合度
  • 5.在外观模式中,通常会有一个外观类(Facade),它充当客户端和子系统之间的中介。
  • 6.外观类知道哪些子系统负责处理请求,并将客户端的请求代理给适当的子系统对象。
  • 7.通过这种方式,客户端只需要与外观类进行交互,而不需要了解系统内部的具体细节和复杂性。
2. 应用场景
  • 1.当系统的复杂度较高时,可以使用外观模式来简化系统的使用。通过提供一个简单的接口,可以将系统的复杂性内部化,对外提供一个简单的接口,使得使用者更加容易使用。
  • 2.当系统中存在多个包含关系复杂的接口时,可以使用外观模式进行封装。将多个复杂的接口封装成一个简单的接口,可以减少客户端所需处理的对象数目,并使得子系统使用起来更加容易。
  • 3.当系统需要对外封闭时,可以使用外观模式来进行封装。外界只能通过一个统一的接口来访问系统,这样可以有效提高系统的安全性。
  • 4.当系统需要进行重构时,可以使用外观模式来进行重构。将系统功能进行重组,减少耦合,从而提高系统的灵活性和可扩展性。
3. 结构图

在这里插入图片描述

4. 构成
  • 1.Facade(外观类):知道哪些子系统负责处理请求;将客户的请求代理给适当的子系统对象。这是模式的核心部分,为子系统的一组接口提供一个统一的高层接口,使得子系统更容易使用。客户端只需要与外观类进行交互,而不需要了解子系统内部的具体细节和复杂性。
  • 2.Subsystem classes(子系统):实现子系统的功能;处理有Facade对象指派的任务;没有Facade的任何相关信息,即没有指向Facade的指针。
  • 3.客户端(Client):客户端与外观类进行交互,通过外观类提供的高层接口访问子系统。客户端不需要了解子系统内部的具体实现细节,只需要知道外观类提供的接口和方法即可。
5. 适用性
  • 1.要为一个复杂子系统提供一个简单接口时,子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类,这使得子系统更具有可重用性,也更容易对子系统进行定制,但也给那些不需要定制子系统的用户带来一些使用上的困难。
  • 2.Facade可以提供一个简单的默认视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层。
  • 3.客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
  • 4.当需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,则可以让它们仅通过Facade进行通信,从而简化了它们之间的依赖关系。
6. 优点
  • 1.简化客户端操作:外观模式为客户端提供了一个简化的、统一的接口,使得客户端无需关心子系统内部的复杂性和实现细节,从而降低了客户端与子系统之间的耦合度。
  • 2.降低系统复杂性:当系统非常复杂时,外观模式可以隐藏子系统内部的复杂性,使得客户端只需要关注与外观类的交互,而无需了解子系统内部的实现细节。
  • 3.提高系统的可维护性:由于外观类将客户端与子系统的交互进行了封装,当子系统内部发生变化时,只需要修改外观类即可,而无需修改所有客户端代码,从而提高了系统的可维护性。
  • 4.灵活的扩展性:当需要添加新的子系统或修改现有子系统时,只需要在外观类中添加或修改相应的代码,而无需修改客户端代码,从而保持了客户端的稳定性。
  • 5.符合“最少知识原则”:外观模式使得客户端只需要与外观类进行交互,而无需了解子系统内部的具体实现细节,这符合了“最少知识原则”,即一个软件实体应当尽可能少地与其他实体发生相互作用。
7. 缺点
  • 1.不符合“开闭原则”:在某些情况下,当需要为子系统添加新的功能时,可能需要修改外观类的代码,从而违反了“开闭原则”(即对扩展开放,对修改封闭)。
  • 2.可能增加系统复杂性:如果外观类设计得过于复杂,可能会增加系统的整体复杂性,使得系统难以理解和维护。
  • 3.不适用于所有场景:外观模式主要适用于子系统相对独立、接口稳定且客户端不需要直接访问子系统内部细节的场景。如果子系统之间存在紧密的联系或者客户端需要直接访问子系统内部细节,那么使用外观模式可能并不合适。
  • 4.可能隐藏了子系统的错误:由于外观类将客户端与子系统的交互进行了封装,当子系统内部出现错误时,这些错误可能会被外观类隐藏起来,使得客户端难以发现和定位问题。
  • 5.可能增加性能开销:在某些情况下,由于外观类需要处理多个子系统的交互,可能会导致性能下降。特别是在处理大量数据或进行复杂计算时,这种性能开销可能会更加明显。
8. java示例
  • 1.子系统接口
package com.learning.facade;

// 点餐子系统接口
public interface MealSubsystem {
    void order();  
    void prepare();  
    void serve();  
}
  • 2.主餐子系统接口
package com.learning.facade;

// 主菜子系统
public class MainFood implements MealSubsystem {
    @Override  
    public void order() {  
        System.out.println("点主餐");
    }  
  
    @Override  
    public void prepare() {  
        System.out.println("准备主餐");
    }  
  
    @Override  
    public void serve() {  
        System.out.println("端上主餐");
    }  
}  
  • 3.甜品子系统接口
package com.learning.facade;

// 甜品子系统
public class Dessert implements MealSubsystem {
    @Override  
    public void order() {  
        System.out.println("点甜品");
    }  
  
    @Override  
    public void prepare() {  
        System.out.println("准备甜品");
    }  
  
    @Override  
    public void serve() {  
        System.out.println("端上甜品");
    }  
}  
  • 4.汤子系统接口
package com.learning.facade;

// 汤品子系统
public class Soup implements MealSubsystem {
    @Override  
    public void order() {  
        System.out.println("点汤");
    }  
  
    @Override  
    public void prepare() {  
        System.out.println("准备汤");
    }  
  
    @Override  
    public void serve() {  
        System.out.println("端上汤");
    }  
}
  • 4.外观类服务员
package com.learning.facade;

/**
 * 外观类 - 服务员
 */
public class Waiter {
    private MealSubsystem mainFood;
    private MealSubsystem soup;  
    private MealSubsystem dessert;  
  
    public Waiter() {  
        this.mainFood = new MainFood();
        this.soup = new Soup();  
        this.dessert = new Dessert();  
    }  
  
    public void orderMeal() {  
        mainFood.order();
        soup.order();  
        dessert.order();  
  
        // 假设准备和送餐是同时进行的  
        prepareAndServe();  
    }  
  
    private void prepareAndServe() {  
        mainFood.prepare();
        soup.prepare();  
        dessert.prepare();  
  
        mainFood.serve();
        soup.serve();  
        dessert.serve();  
    }  
}  
  • 4.客户端
package com.learning.facade;

// 客户端
public class Client {  
    public static void main(String[] args) {  
        Waiter waiter = new Waiter();
        // 顾客告诉服务员点餐,服务员负责处理整个点餐、准备和送餐流程
        waiter.orderMeal();
    }  
}
  • 5.示例截图
    在这里插入图片描述

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

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

相关文章

OM电商系统asp.net

OM电商系统,可以让顾客全面了解商品的详细信息,消除网上购物的信息不对称问题。通过商品分类来组织众多的商品,方便顾客找到所需要的商品。提供客服顾客互动机制,提高顾客的参与度。通过设计合理的订单处理流程,提高顾…

JavaSE:String类常用方法(巨详细)

1、引言 在学习C语言时,我们就已经了解了字符串,但是在C语言中字符串只能用字符数组或者指针来表示,没有特定的字符串类型,而在Java中,我们有了字符串这一特定的类型---String类。 2、String类的常用方法 2.1 字符串…

第15章-超声波避障功能 HC-SR04超声波测距模块详解STM32超声波测距

这个是全网最详细的STM32项目教学视频。 第一篇在这里: 视频在这里 STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随 15.1-超声波测距 完成超声波测距功能、测量数据显示在OLED屏幕上 硬件介绍 使用&#…

OpenHarmony实战开发——宿舍全屋智能开发指南

项目说明 基于OpenAtom OpenHarmony(以下简称“OpenHarmony”)、数字管家开发宿舍全屋智能,实现碰一碰开门、碰一碰开灯、碰一碰开风扇以及烟感检测。因为各项目开发流程大体相似,本文主要以碰一碰开门为例介绍如何在现有OpenHar…

野外作战武器操作3D模拟实操仿真训练以便老兵能适应不同的训练需求

强国必须强军,我国在军事方面的投入持续加大,自然在军事武器培训方面不容忽视,在军事领域,3D模拟展示不仅提升了军事训练的效率,还为我们提供了更加直观、真实的武器体验。 首先,3D军事武器模拟展示能够提供…

Django革新者:突破传统,构建下一代Web应用

书接上文 —— 家园建筑师:用Django打造你的Web帝国,从前面的学习中,咱们我们经历了一个完整的Django Web开发之旅,涵盖了从基础概念到高级特性的各个方面: 引言:介绍了企业级Web框架的需求,并概…

分享个自用的 Nginx 加强 WordPress 防护的规则

Nginx WordPress 的组合是目前非常普及的组合了,我们完全可以借助 Nginx 规则来加强 WordPress 的防护,提高 WordPress 的安全性,今天明月就给大家分享个自用的 Nginx 针对 WordPress 的防护规则,部分规则大家只需要根据自己的需要…

ABB焊接功能介绍

1.基本配置 1.2配置Robot Ware Arc 2.焊接语句 2.1直线焊接语句 过渡点指令必须位于起弧指令与熄弧指令之间,不能单独使用。 2.2直线焊接示例 2.3圆弧焊接语句 2.4圆弧焊接示例 2.5摆动参数 关于ABB焊接机器人摆动参数设定 一般情况下,主要设置以…

[Linux]磁盘管理

一.Linux磁盘管理的原理 磁盘分区与Linux的目录是借助"挂载机制"链接的,将一个分区与一个目录连接起来。访问目录,相当于访问某块分区 lsblk命令: lsblk命令可以查看磁盘分区,以及每个分区所挂载的目录 lsblk -f 可以查看更细节的…

利用NewGIS平台将FME模板发布为接口

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 一、模板编写 二、发布模板 三、接口获取 四、移动端调用 ​​​​​ 前言 在实际的应用生产过程中,尤其是移动端GIS软件的开发,针对一些闭…

win11中文文件名称乱码解决方案

解压后出现以下的乱码 解决方案 步骤1.winR 输入intl.cpl 或 windows 自带的搜索搜“intl.cpl”,打开这个面板控制项 步骤2.在新打开的区域面板中,选择“管理”标签页,点击下方的“更改系统区域设置”按钮 步骤3.取消"Beta版…"选…

Nginx的配置与调试

目录 1、安装Nginx 2、Nginx的配置文件结构 2.1 Nginx的全局配置 2.2 HTTP服务器配置 2.3 HttpGzip模块配置 2.4 负载均衡配置 2.5 server虚拟主机配置 2.6 location URL匹配配置 2.7 StubStatus模块配置 1、安装Nginx 在安装Nginx之前,需确保系统已经安装…

Day38 代码随想录打卡|二叉树篇---二叉树的最大深度

题目(leecode T104): 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 递归法: 递归法首先将根节点作为参数传入,随后每一轮传入当前节点的…

【openlayers系统学习】3.3假彩色图像合成(三个波段合成假彩色图像)

三、假彩色图像合成 在上一步中,我们使用 ol/source/GeoTIFF​ 源从单个多波段源(具有红色、绿色、蓝色和Alpha波段)渲染真彩色图像。在下面这个例子中,我们将从可见光谱之外提取数据,并使用它来呈现假彩色合成。 我…

Linux echo命令(在终端输出文本)

文章目录 Linux Echo命令深度解析简介命令语法常见选项- -n:不输出行尾的换行符,这意味着输出后不会换到下一行。- -e:启用反斜杠转义的解释,允许使用特殊字符。- -E:禁用反斜杠转义的解释(默认选项&#x…

简单得阴影引导实现

效果如下: 实现方式: 1、引入三方库: implementation io.github.razerdp:BasePopup:3.2.0 2、代码实现 class NewUserGuide3Popup : BasePopupWindow {constructor(activity: Activity) : super(activity)constructor(context: Context) : super(con…

如何开启tomcat管理功能

1 、修改conf/tomcat-users.xml <role rolename"manager-gui"/> <user username"tomcat" password"tomcat" roles"manager-gui"/>2、修改webapps/manager/META-INF/context.xml <Valve className"org.apache.cata…

动态规划part02 Day42

LC62不同路径 LC63不同路径II(超时10min) 超时原因分析&#xff1a;思路想错了&#xff0c;即便是正确思路初始化也有点问题&#xff0c;应该将不必要的判断逻辑引入初始化的过程中初始化&#xff1a; 从左上角到[i][0]和[0][j]都只有一条路径dp[i][0]1和dp[0][j]1引入故障&am…

Go 错误日志处理

是不是所有的 if err ! nil 的地方都应该输出错误日志&#xff1f; 打印过多的错误日志会导致日志文件变得冗长和难以阅读。 其次&#xff0c;重复的错误信息会增加冗余。 此外&#xff0c;每一层都打印错误日志&#xff0c;一旦错误信息设计不当&#xff0c;可能会导致上下…

【iOS】——GCD再学习

文章目录 一、GCD的定义二、GCD 任务和队列1.任务2.队列 三、GCD 的使用1.创建队列2.创建任务3.队列任务 组合方式并发队列 同步执行异步执行 并发队列同步执行 串行队列异步执行 串行队列同步执行 主队列在主线程中调用 同步执行 主队列在其它线程中调用 同步执行 主队…