23种设计模式之一————外观模式详细介绍与讲解

news2024/11/24 13:57:09

外观模式详细讲解

  • 一、概念
  • 二、 外观模式结构
      • 核心思想及解释
      • 模式的UML类图
      • 模式角色
      • 应用场景
      • 模式优点
      • 模式缺点
  • 三、实例演示
      • 图示
      • 代码展示
      • 运行结果

一、概念

外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用来访问系统中的一群接口,从而简化客户端与系统之间的交互。外观模式通过引入一个外观类来封装子系统的复杂性,使得客户端只需要与外观类交互,而无需直接与子系统的各个组件打交道。

二、 外观模式结构

核心思想及解释

外观模式的核心思想是简化复杂系统的接口。它提供一个统一的接口,客户端通过这个接口与复杂子系统进行交互,而不需要了解子系统的详细工作原理。这种模式允许用户避免直接处理复杂的子系统组件,可以更加简单地对子系统进行访问和管理。

模式的UML类图

在这里插入图片描述

模式角色

外观角色(Facade):这是外观模式的核心角色,它提供了一个简化的接口,用于访问子系统中的功能。外观类的作用是封装复杂的子系统操作,让外部客户端无需了解内部细节就能进行交互。
子系统角色(Subsystem):这些是实际执行具体任务的类或模块。它们可能包含多个类和更复杂的逻辑,对于客户端来说,直接与这些子系统交互可能会非常复杂。
客户角色(Client):客户端使用外观类提供的接口与子系统进行交互。通过这种方式,客户端可以简化其代码,因为它只需要与外观类打交道,而不是直接与复杂的子系统打交道。

应用场景

1.系统复杂度较高:当系统的某一子系统变得过于复杂,不容易使用时,可以使用外观模式进行简化。它可以将系统的复杂性内部化,对外提供一个简单的接口,使得使用者更加容易使用。
2.系统中存在多个包含关系复杂的接口:当系统中存在多个接口之间的依赖关系比较复杂时,外观模式可以进行封装,将复杂性内部化,从而简化其使用和维护。
3.需要对外封闭系统:当系统需要对外封闭,外界只能通过一个统一的接口来访问系统时,可以使用外观模式进行封装,这样可以有效提高系统的安全性。
4.系统需要进行重构:当系统需要进行重构,需要对原有的代码进行优化和改进时,可以使用外观模式进行重构,使得代码更加易于理解和维护。同时,使用外观模式可以将系统功能进行重组,减少耦合,从而提高系统的灵活性和可扩展性。
5.简化系统接口:客户端需要使用一个简单易用的接口来操作整个系统,而不需要关心系统的内部实现。
6.封装复杂逻辑:系统内部的实现非常复杂,需要通过外观模式来将其封装起来,从而便于管理和维护。
7.解耦系统组件:系统内部的各个组件之间存在较高的耦合度,需要通过外观模式来降低其耦合度,从而提高系统的可扩展性和灵活性。

模式优点

  • 简化接口:客户端只需与外观类交互,无需了解系统的复杂性。
  • 解耦客户端和子系统:外观类作为中介者,降低了客户端和子系统之间的耦合度。
  • 提高灵活性:可以随时修改外观类以适应系统变化,而不会影响客户端代码。

模式缺点

  • 不符合“开闭原则”:如果新增子系统或删除子系统,可能需要修改外观角色的代码,这在一定程度上违反了“开闭原则”。
  • 可能隐藏了子系统的复杂性:如果外观角色设计得过于复杂,可能会隐藏子系统的复杂性,使得客户端难以理解和使用。
  • 封装过度导致灵活性降低:如果外观类封装了过多的子系统功能,可能会导致其变得过于庞大和复杂,反而增加了理解和维护的难度。当需要修改系统内部实现时,可能需要修改外观类,这可能会影响到其他与外观类交互的客户端。

三、实例演示

图示

在这里插入图片描述

代码展示

package task1;

public class GuaHao {
	private String keshi;

	public GuaHao(String keshi) {
		this.keshi = keshi;
	}

	public boolean IsTrue() {
		if (keshi != null) {
			return true;
		} else
			return false;
	}

}
package task1;

public class Menzhen {
	private GuaHao guaHao;

	public Menzhen(GuaHao guaHao) {
		this.guaHao = guaHao;
	}

	public String check() {
		String str = "健胃消食片";
		if (guaHao.IsTrue()) {//判断是否挂号
			return str;
		} else
			return null;

	}

}
package task1;

public class Huajia {
	private Menzhen menzhen;

	public Huajia(Menzhen menzhen) {
		this.menzhen = menzhen;
	}

	public double Getprice() {
		if (menzhen.check() != null) {
			System.out.println("开的药是:"+menzhen.check());
			return 20;
		} else
			return 0;
	}
}
package task1;

public class Pay {
	private Huajia price;

	public Pay(Huajia price) {
		this.price = price;
	}

	public boolean IsPay() {
		System.out.println("已缴费" + price.Getprice());
		return true;
	}
}
package task1;

public class Medicine {
	public Pay isPay;

	public Medicine(Pay isPay) {
		this.isPay = isPay;
	}

	public void GetMedicine() {
		if (isPay.IsPay()) {
			System.out.println("已取药");
		}
	}

}

然后,我们创建一个外观类,它将子系统的功能进行封装:

package task1;

public class Facade {
	private GuaHao guaHao;
	private Menzhen menzhen;
	private Huajia huajia;
	private Pay pay;
	private Medicine medicine;
	private String keshi;

	public Facade(String keshi) {
		this.keshi = keshi;
		guaHao = new GuaHao(keshi);
		menzhen = new Menzhen(guaHao);
		huajia = new Huajia(menzhen);
		pay = new Pay(huajia);
		medicine = new Medicine(pay);

	}

	public void check() {
		System.out.println("挂号:"+keshi);
		medicine.GetMedicine();
		

	}

}

最后,我们可以在客户端代码中使用外观类:

package task1;

public class Test {
	public static void main(String[] args){
		Facade facade = new Facade("内科");
		facade.check();
	}

}

运行结果

在这里插入图片描述
在这个示例中,GuaHaoMenzhenHuajiaPayMedicine代表子系统中的不同组件,它们各自负责挂号、门诊、划价、付费和取药。Facade作为外观类,提供了一个check()方法,该方法调用了所有必要的子系统操作来检查,从而简化了客户端的使用。客户端只需要调用外观类的一个方法,而无需了解每个子系统的具体实现细节。
"博主用心写,读者点关注;互动传真情,知识不迷路

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

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

相关文章

自动驾驶---Tesla的自动驾驶技术进化史(PerceptionPlanning)

1 前言 笔者在专栏《自动驾驶Planning模块》中已经详细讲解了传统自动驾驶Planning模块的内容:包括行车的Behavior Planning和Motion Planning,以及低速记忆泊车的Planning(最开始有15篇,目前逐渐更新到17篇)。读者对整…

【C语言】文件的编译链接和预处理

文件的编译链接和预处理 程序的翻译环境和执行环境翻译环境预处理(预编译)过程编译过程汇编过程链接过程 运行环境 预处理详解预处理符号预处理指令#define#define定义标识符#define定义宏#define替换规则 #与###的使用##的使用 带有副作用的宏参数宏与函…

C++面向对象的第二大特性:继承

1.继承的介绍 首先容我先向大家举一个列子: 我这里定义了一个Person的类 class Person { protected:string name;int age;string address;}; 在这个基础上,我要定义一个关于Student , Worker 的类 由于Student Worker都具有Person类中的成员变量 &#xff0c…

C语言自定义类型:结构体

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 C语言自定义类型:结构体 收录于专栏【C语言学习】 本专栏旨在分享学习C语言学习的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. 结…

EyeMock下载与使用教程

视频眼神修复直视镜头的AI具有极高的灵活性和适应性。它可以根据不同的拍摄环境和主播需求进行个性化设置,确保最佳的视觉呈现效果。在直播互动中,主播可能因为分神或疲劳而失去与观众的直视,这款工具能够迅速识别并修复这一问题,…

苹果M4性能分析:进步神速?还有多少空间?

2024年初,苹果推出了M4处理器,令人意外的是,它的发布距离M3发布仅仅过去了半年时间。更让人惊讶的是,M4首次亮相于iPad Pro。这一新处理器不仅仅是M3的简单升级版本,而是一次全面的架构优化。本文将详细分析M4处理器的…

网络工程师备考1——基础学习

认识设备 1 交换机 一、什么是交换机? 实现不同电脑之间数据的转发 换机是一种用于电(光)信号转发的网络设备。 它可以为接入交换机的任意两个网络节点提供独享的电信号通路。最常见的交换机是以太网交换机。交换机工作于OSI参考模型的第二层,即数据…

sw套合样条曲线

套合样条曲线,可以变成一条曲线,然后可以进行分段

sql select获取mysql所有数据库,指定数据库下的所有表名

介绍一下 MySQL 8.0 中默认安装的几个系统数据库/模式。 当我们安装 MySQL 8.0 并初始化数据库之后,默认会创建以下系统数据库: mysql,存储了 MySQL 服务器正常运行所需的各种信息。 information_schema,提供了访问数据库元数据…

黑马点评1——短信篇(基于session)

🌈hello,你好鸭,我是Ethan,一名不断学习的码农,很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 🏃人生之义,在于追求,不在成败,勤通…

使用DataGrip连接跳板机后再连接远程服务器的mysql数据库

相比配置本地数据库就是多了一步SSH/SSL配置。 添加新的mysql连接,选择SSH/SSL,勾选Use SSH tunnel: 点击右边的…配置跳板机连接,输入账号密码,然后保存: 接着配置General,里面填上要连接的数…

【蓝桥杯选拔赛真题76】python找出元素 第十四届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python找出元素 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python找出元素 第十四届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

谷歌浏览器安装devtools工具

在浏览器中输入极简插件,然后打开如下的网页,在搜素框中输入vue 出现下图 点击推荐下载 (地址:https://chrome.zzzmh.cn/info/nhdogjmejiglipccpnnnanhbledajbpd) 打开谷歌浏览器如图 选择“扩展程序” 点开之后&…

抖音跳转微信卡片制作教程 小白也能搞

实测可以正常跳转,很牛逼,给大家分享一下~ 这是我做出来抖音发出去的效果,大家会制作了可以去卖钱,市场上一个这个卡片都要卖50-200,很不错的!! https://pan.baidu.com/s/1xPmGAWPcbAp7eXg7Dc…

防范TOCTOU竞态条件攻击

防范TOCTOU竞态条件攻击 在软件开发过程中,我们常常会遇到需要在使用资源之前检查其状态的情况。然而,如果资源的状态在检查和使用之间发生了变化,那么检查的结果可能会失效,导致软件在资源处于非正常状态时执行无效操作。这种时…

java微服在使用nacos注册中心时,ribbon负载均衡时给部分feign client使用静态serverList

我看很多贴子都是针对eureka环境下,做静态serverList配置,目前国内大部分都用Nacos,所以便研究了一下。 micore-service-x:ribbon:listOfServers: ip1:port,ip2:port2NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBased…

Java基础-反射原理

总结放前面: 反射是可以通过一个类对象或类名称获取到该类的全部信息(属性和方法),包括为权限为private。 要使用反射第一步,要获取的类的Class对象,该Class对象存放在堆区,于类加载时创建&…

每日练习之完全背包——兑换零钱,完全背包问题总结

兑换零钱 题目描述 运行代码 #include<bits/stdc.h> #include<iostream> using namespace std; const int mod1e97; int a[20]{1,2,5,10,20,50,100,200,500,1000,2000,5000,10000},dp[100010]; int main() {dp[0]1;for(int i0;i<13;i)for(int ja[i];j<1000…

汇聚荣:新手做拼多多应该注意哪些事项?

新手在拼多多开店&#xff0c;面临的是竞争激烈的市场和复杂的运营规则。要想在这个平台上脱颖而出&#xff0c;必须注意以下几个关键事项。 一、市场调研与定位 深入了解市场需求和竞争对手情况是新手开店的首要步骤。选择有潜力的细分市场&#xff0c;并针对目标消费者群体进…

LaTeX 2022软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; LaTeX 2022是基于ΤΕΧ的一种排版系统&#xff0c;特别适用于生成科技和数学文档的高质量打印。它可用于各种文档类型&#xff0c;从简单信函到完整…