23种设计模式之外观模式

目录

  • 1. 简介
  • 2. 代码
    • 2.1 SelectFoodService (选择食品)
    • 2.2 PayService (支付服务)
    • 2.3 TakeService (制作服务)
    • 2.4 OrderService (下单服务)
    • 2.5 Food (食品)
    • 2.6 TackingSystem (外观类)
    • 2.7 Test (测试类)
  • 3. 优缺点
  • 3. 总结

1. 简介

外观模式是一种结构型设计模式。它为子系统中的一组接口提供了一个统一的高层接口,这个高层接口使得子系统更容易使用。就好像给一个复杂的机器(子系统)安装了一个简单的控制面板(外观类),用户通过操作这个控制面板就能轻松地使用机器的各种功能,而不需要了解机器内部复杂的结构和各个部件(子系统中的接口)是如何协同工作的。

例如,考虑一个计算机系统,它包含了 CPU、硬盘、内存等多个组件,每个组件都有自己复杂的操作接口。通过外观模式,可以创建一个 “计算机启动” 外观类,它内部封装了 CPU 初始化、硬盘加载系统文件、内存自检等操作。用户只需要调用 “计算机启动” 这个简单的操作,而不用去分别调用每个组件的复杂操作。

外观模式的结构组成

  • 外观类(Facade Class
    这是外观模式的核心。外观类知道哪些子系统类负责处理请求,并将客户的请求代理给适当的子系统对象。它简化了与子系统的交互方式,对外提供了一个更加简单、统一的接口。例如,在上述计算机启动的例子中,“计算机启动” 类就是外观类。
  • 子系统类(Sub - system Classes
    这些是实现具体功能的类,它们各自负责一个特定的、复杂的功能部分。在计算机系统中,CPU 类、硬盘类、内存类等都是子系统类。它们本身的操作可能很复杂,但外观类会对它们进行整合,使得用户不需要直接接触这些复杂的操作。

2. 代码

这里用点餐系统举例子。

2.1 SelectFoodService (选择食品)

public class SelectFoodService {public void select(String foodName){System.out.println("正在选择" + foodName + "。。。");}
}

2.2 PayService (支付服务)

public class PayService {public void pay(){System.out.println("正在支付。。。");}public boolean checkBanlance(){System.out.println("正在检查用户余额。。。");return true;}
}

2.3 TakeService (制作服务)

public class TakeService {public void taking(){System.out.println("正在制作外卖。。。");}
}

2.4 OrderService (下单服务)

public class OrderService {public void makeOrder(){System.out.println("正在下单。。。");}
}

2.5 Food (食品)

public class Food {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

2.6 TackingSystem (外观类)

public class TackingSystem {private SelectFoodService selectFoodService;private PayService payService;private OrderService orderService;private TakeService takeService;public TackingSystem(){selectFoodService = new SelectFoodService();payService = new PayService();orderService = new OrderService();takeService = new TakeService();}public void orderTacking(Food food){// 点餐selectFoodService.select(food.getName());// 校验余额boolean isPay = payService.checkBanlance();// 支付if(isPay){payService.pay();takeService.taking();orderService.makeOrder();}}
}

2.7 Test (测试类)

public class Test {public static void main(String[] args) {Food food = new Food();food.setName("西红柿鸡蛋面");TackingSystem tackingSystem = new TackingSystem();tackingSystem.orderTacking(food);}
}

输出结果:

正在选择西红柿鸡蛋面。。。
正在检查用户余额。。。
正在支付。。。
正在制作外卖。。。
正在下单。。。

3. 优缺点

外观模式的优点

  • 简化接口
    为复杂的子系统提供了一个简单的、统一的接口,降低了客户端与子系统之间的耦合度。客户端只需要和外观类交互,不需要了解子系统内部的复杂细节,就像在家庭影院系统中,用户只需要通过外观类的 “watchMovie” 和 “endMovie” 方法就能轻松控制整个系统,而不用分别去操作每个设备。
  • 提高可维护性和可扩展性
    当子系统内部的结构和功能发生变化时,只要外观类的接口保持不变,客户端代码就不需要修改。例如,如果要升级 DVD 播放器的内部软件,只要它的 “turnOn” 和 “turnOff” 接口不变,外观类和客户端代码都不需要调整。同时,新的子系统可以很容易地添加到外观类中,方便系统的扩展。
  • 实现了层次隔离
    外观模式可以将系统的高层逻辑和底层实现分离开来。高层逻辑通过外观类来体现,底层的子系统则负责具体的功能实现。这种层次隔离使得代码的结构更加清晰,便于不同层次的开发人员分别进行开发和维护。

外观模式的缺点

  • 不符合开闭原则的潜在风险
    如果外观类的接口需要修改,可能会影响到所有使用该外观类的客户端。因为外观类是客户端和子系统之间的桥梁,一旦这个桥梁的接口发生变化,就可能需要修改客户端代码。例如,如果要在家庭影院系统的外观类中添加一个新的功能,如 “暂停电影”,那么所有使用这个外观类的客户端代码可能都需要相应地修改,这在一定程度上不符合开闭原则(对扩展开放,对修改关闭)。
  • 外观类可能会变得过于复杂
    如果子系统本身非常庞大和复杂,外观类需要整合大量的子系统接口,那么外观类可能会变得臃肿和复杂。这可能会导致外观类的维护成本增加,而且可能会降低代码的可读性。例如,一个大型企业级软件系统的外观类,如果要整合众多的子系统,如数据库管理系统、消息队列系统、文件存储系统等,外观类的代码可能会变得非常复杂。

3. 总结

其实就是定义多个子系统,一个总系统,随后总系统初始化多个子系统,然后使用就行了。

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

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

相关文章

vue3 路由跳转携带参数以及其他页面接收参数

vue3 路由跳转携带参数以及其他页面接收参数 传参页面 <script setup> import { useRouter } from "vue-router"; const router useRouter();// 路由 const goToDetail () > {router.push({ path: /about, query: { id: 123 } }); }; function goToDeta…

MeterSphere VS 其他开源接口测试工具

对比项 swagger yapi postman httprunner2.x/3.x jmeter metersphere UI界面 支持支持支持 不支持&#xff08;无界面/UI不够便捷 脚本编写量大 文档不够清晰&#xff09; 支持支持 单接口 支持支持支持支持支持支持 业务场景自动化 不支持支持支持支持支持支持 操作数据…

STM32CUBEIDE FreeRTOS操作教程(十):interrupt on/off中断开关

STM32CUBEIDE FreeRTOS操作教程&#xff08;十&#xff09;&#xff1a;interrupt on/off中断开关 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发…

【系统架构设计师论文】微服务架构设计与实践

一、微服务架构概述 1.1 什么是微服务架构? 微服务架构(Microservices Architecture)是一种将应用程序拆分为多个小型服务的架构模式,每个服务都可以独立开发、部署、扩展,并通过轻量级的通信协议(通常是 HTTP/REST 或 gRPC)进行交互。这种架构的核心思想是将大型单体…

长安汽车嵌入式面试题及参考答案

数据结构中的堆栈和编程中的堆栈有什么区别? 在数据结构中,堆栈是一种抽象的数据类型。它遵循后进先出(LIFO)的原则。从操作角度来看,有入栈(push)和出栈(pop)操作。例如,想象有一个装有盘子的栈,只能从栈顶放入和取出盘子。数据结构中的堆栈主要关注其逻辑结构和操…

Python学习38天

class Person:def __init__(self, name, age, job):self.name nameself.age ageself.job job# 重写函数返回属性def __str__(self):return f"{self.name}--{self.age}--{self.job}"# 冒泡排序法 def bubble_sort(my_list: list[Person]):"""冒泡排…

Python 调用 Umi-OCR API 批量识别图片/PDF文档数据

目录 一、需求分析 二、方案设计&#xff08;概要/详细&#xff09; 三、技术选型 四、OCR 测试 Demo 五、批量文件识别完整代码实现 六、总结 一、需求分析 市场部同事进行采购或给客户报价时&#xff0c;往往基于过往采购合同数据&#xff0c;给出现在采购或报价的金额…

docker x86环境构建arm镜像出现failed to fetch oauth token问题

问题&#xff1a;最近在使用x86的MAC机器准备打包arm的镜像时使用命令如下 docker buildx build --platform linux/arm64 --load --no-cache -t deepface:v1-arm .出现连接问题 [] Building 31.7s (3/3) FINISHED …

C语言中map的用法和其他数据结构的区别

在C语言中&#xff0c;没有直接内置的map数据结构&#xff08;类似于C的std::map&#xff09;&#xff0c;但可以通过结构体、数组、链表或哈希表来实现类似功能。下面将从map的概念、实现方法和与其他数据结构的区别等方面进行详细讲解。 一、Map的概念 Map是一种键值对&…

【AI系统】AI 编译器基本架构

AI 编译器基本架构 在上一篇文章中将 AI 编译器的发展大致分为了 3 个阶段&#xff0c;分别为 1&#xff09;朴素编译器、2&#xff09;专用编译器以及 3&#xff09;通用编译器。 本文作为上一篇文章 AI 编译器架构的一个延续&#xff0c;着重讨论 AI 编译器的通用架构。首先…

java版工程项目管理系统源码:Spring Cloud与前后端分离的完美结合

在现代化的工程项目管理中&#xff0c;一套功能全面、操作便捷的系统至关重要。本文将介绍一个基于Spring Cloud和Spring Boot技术的Java版工程项目管理系统&#xff0c;结合Vue和ElementUI实现前后端分离。该系统涵盖了项目管理、合同管理、预警管理、竣工管理、质量管理等多个…

近几年,GIS专业的五类就业方向!

近二十几年来&#xff0c;地理信息科学毕业生的就业方向在不断发生变化。 早期的地理信息科学技术主要应用于政府部门&#xff0c;因此学生就业主要在高校、交通运输、规划勘测设计、国土、矿业、水利电力、通讯、农林、城市建设、旅游等国家政府部门或事业单位。 随着地理信…

css选择当前元素前面的一个元素

选择text-danger前面的ant-divider: .ant-divider:has( .text-danger) {display: none; }

动态代理如何加强安全性

在当今这个信息爆炸、网络无孔不入的时代&#xff0c;我们的每一次点击、每一次浏览都可能留下痕迹&#xff0c;成为潜在的安全隐患。如何在享受网络便利的同时&#xff0c;有效保护自己的隐私和信息安全&#xff0c;成为了每位网络使用者必须面对的重要课题。动态代理服务器&a…

el-table 纵向 横向 多级表头

<el-table :data"tableData" class"diaTable":span-method"handleSpanMethod"border:header-cell-style"{background:#292929,color:#fff}"><!-- 纵向表头 --><el-table-column label"纵向表头" width"…

网页端五子棋对战(二)---数据库连接用户登录注册接口设计postman验证

文章目录 1.用户模块--数据库的设计1.1idea新建db.sql文件1.2mysql建库建表 2.使用mybatis操作数据库2.1修改spring配置文件2.2创建实体类用户user2.3创建Mapper接口2.4实现xml配置文件 3.前后端交互接口架构4.后端代码实现4.1登录模块4.2注册模块4.3获取用户信息 5.postman验证…

【导航查询】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

Nginx篇之实现nginx转发兼容HTTP和Websocket两种协议

Nginx实现同时兼容http协议和websocket协议 map $http_upgrade $eop_gateway {default "eop-gateway-http";websocket "eop-gateway-ws"; }# 控制 Connection header map $http_upgrade $connection_upgrade {default "keep-alive"; # HTTP …

谷歌浏览器中搜索引擎的设置与管理

谷歌浏览器作为全球最受欢迎的网络浏览器之一&#xff0c;以其高速、稳定和丰富的功能深受用户喜爱。对于许多用户来说&#xff0c;自定义和管理搜索引擎是提升浏览体验的重要一环。本文将详细介绍如何在谷歌浏览器中设置和管理搜索引擎&#xff0c;包括如何修改默认搜索引擎、…

【Linux 篇】Docker 容器星河与镜像灯塔:Linux 系统下解锁应用部署奇幻征程

文章目录 【Linux 篇】Docker 容器星河与镜像灯塔&#xff1a;Linux 系统下解锁应用部署奇幻征程前言一 、docker上部署mysql1. 拉取mysql镜像2. 创建容器3. 远程登录mysql 二 、docker上部署nginx1. 拉取nginx镜像2. 在dockerTar目录下 上传nginx.tar rz命令3. 创建nginx容器4…