Java设计模式:外观模式之优雅门面(九)

在这里插入图片描述

码到三十五 : 个人主页

心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 !


在软件工程中,设计模式是解决常见设计问题的经验总结,它为开发者提供了一种通用的、可复用的解决方案。外观模式(Facade
Pattern)作为结构型设计模式的一种,通过为子系统中的一组接口提供一个统一的高层接口,使得子系统更加容易使用。

目录

    • 一、外观模式的起源与背景
    • 二、外观模式的组件
      • 2.1. Facade(外观类)
      • 2.2. Subsystem Classes(子系统类)
      • 2.3. Client(客户端)
    • 三、外观模式的优势分析
    • 四、外观模式实现方式
    • 五、外观模式的应用场景举例
    • 总结

[参见]:

Java设计模式:核心概述(一)

Java设计模式:单例模式之六种实现方式详解(二)

Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)

Java设计模式:建造者模式之经典与流式的三种实现(四)

Java设计模式:适配器模式的三种形式(五)

Java设计模式:深入装饰器模式的三种写法(六)

Java设计模式:组合模式之透明与安全的两种实现(七)

Java设计模式:代理模式的静态和动态之分(八)

一、外观模式的起源与背景

在复杂的软件系统中,往往存在多个子系统或组件协同工作的情况。这些子系统可能由不同的团队开发,使用不同的技术栈,具有各自独特的接口和依赖关系。当客户端需要使用这些子系统时,可能需要了解并调用多个接口,处理复杂的依赖关系,这无疑增加了客户端的使用难度。

为了解决这个问题,外观模式应运而生。它通过一个外观类(Facade)来整合子系统中的接口,为客户端提供一个统一的、更简单的接口。客户端只需与外观类交互,而无需了解子系统的具体实现细节和复杂性。

二、外观模式的组件

在这里插入图片描述

2.1. Facade(外观类)

  • 外观类是外观模式的核心组件,它提供了客户端所需的统一接口。
  • 外观类内部持有对子系统对象的引用,负责将客户端的请求转发给相应的子系统对象处理。
  • 外观类可以对子系统的接口进行封装和抽象,使得客户端无需了解子系统的具体实现细节。
  • 外观类还可以对子系统的返回结果进行整合和处理,以更友好的方式呈现给客户端。

2.2. Subsystem Classes(子系统类)

  • 子系统类是实现具体功能的类,它们可能具有复杂的接口和相互依赖关系。
  • 在外观模式中,子系统类被隐藏起来,客户端不直接访问它们。而是通过外观类来间接访问子系统。
  • 子系统类之间可能存在复杂的交互和协作关系,但这些细节对客户端来说是透明的。

2.3. Client(客户端)

  • 客户端是使用外观类来访问子系统的类。
  • 客户端只需了解外观类提供的接口,而无需了解子系统的具体实现细节和复杂性。
  • 通过使用外观类,客户端可以更加简洁、方便地访问子系统,降低了客户端的使用难度和耦合度。

三、外观模式的优势分析

  1. 简化客户端使用:通过提供一个统一的接口,外观模式使得客户端可以更加简洁、方便地访问子系统。客户端无需了解子系统的复杂性和实现细节,只需调用外观类提供的方法即可完成操作。这降低了客户端的使用难度和学习成本。
  2. 降低耦合度:外观模式将客户端与子系统解耦,客户端只需与外观类交互,而无需直接依赖子系统。当子系统发生变化时,只需要修改外观类而无需修改客户端代码。这提高了系统的可维护性和可扩展性。
  3. 隐藏系统复杂性:外观类封装了子系统的实现细节和复杂性,为客户端提供了一个清晰的、一致的视图。这使得客户端可以专注于自己的业务逻辑,而无需关心子系统的具体实现和交互细节。这有助于保护子系统的内部结构和实现细节不被外部直接访问和修改。
  4. 提高系统灵活性:通过引入外观类作为中介层,我们可以更加灵活地组织和管理子系统。我们可以根据需要添加、删除或修改子系统的组件,而无需修改客户端代码。这提高了系统的灵活性和可配置性。

四、外观模式实现方式

我们模拟一个银行系统,其中包括账户管理、贷款服务和存款服务等多个子系统。然后使用外观模式来提供一个统一的接口给客户端使用。

首先,我们定义几个子系统类(Subsystem Classes),这些类模拟了银行系统中的不同组件。

// 账户管理子系统
class AccountManagement {public void createAccount(String accountName) {System.out.println("为 " + accountName + " 创建账户。");}public void closeAccount(String accountName) {System.out.println("关闭 " + accountName + " 的账户。");}
}// 贷款服务子系统
class LoanService {public void applyForLoan(String accountName, double amount) {System.out.println(accountName + " 申请了 " + amount + " 的贷款。");}public void approveLoan(String accountName) {System.out.println(accountName + " 的贷款已被批准。");}
}// 存款服务子系统
class DepositService {public void deposit(String accountName, double amount) {System.out.println(accountName + " 存款 " + amount + "。");}public void withdraw(String accountName, double amount) {System.out.println(accountName + " 取款 " + amount + "。");}
}

接下来,我们创建外观类(Facade),该类将封装这些子系统类,并为客户端提供一个统一的接口。

// 银行外观类
class BankFacade {private AccountManagement accountManagement;private LoanService loanService;private DepositService depositService;// 构造函数,初始化子系统对象public BankFacade() {accountManagement = new AccountManagement();loanService = new LoanService();depositService = new DepositService();}// 提供给客户端的简化方法 - 开户并存款public void openAccountAndDeposit(String accountName, double amount) {accountManagement.createAccount(accountName);depositService.deposit(accountName, amount);System.out.println("开户并存款操作完成。");}// 提供给客户端的简化方法 - 申请贷款并批准public void applyAndApproveLoan(String accountName, double amount) {loanService.applyForLoan(accountName, amount);loanService.approveLoan(accountName);System.out.println("申请并批准贷款操作完成。");}// 提供给客户端的简化方法 - 取款并关闭账户public void withdrawAndCloseAccount(String accountName, double amount) {depositService.withdraw(accountName, amount);accountManagement.closeAccount(accountName);System.out.println("取款并关闭账户操作完成。");}
}

最后,我们创建客户端(Client)来使用外观类。

// 客户端
public class BankClient {public static void main(String[] args) {// 创建银行外观对象BankFacade bankFacade = new BankFacade();// 客户端通过银行外观对象调用操作bankFacade.openAccountAndDeposit("张三", 10000);bankFacade.applyAndApproveLoan("张三", 5000);bankFacade.withdrawAndCloseAccount("张三", 2000);}
}

客户端通过BankFacade类的简化方法来完成一系列复杂的操作,如开户并存款、申请贷款并批准、取款并关闭账户等。客户端无需了解子系统的具体实现细节和它们之间的交互方式。

运行BankClient类的main方法,看到以下输出:

为 张三 创建账户。
张三 存款 10000.0。
开户并存款操作完成。
张三 申请了 5000.0 的贷款。
张三 的贷款已被批准。
申请并批准贷款操作完成。
张三 取款 2000.0。
关闭 张三 的账户。
取款并关闭账户操作完成。

通过银行外观类,客户端成功地完成了一系列复杂的银行业务操作,而无需直接与各个子系统打交道。这样的设计降低了客户端与子系统之间的耦合度,提高了系统的可维护性和可扩展性。

五、外观模式的应用场景举例

  1. 在大型软件系统中整合不同模块:在大型软件系统中,往往存在多个模块或组件协同工作的情况。这些模块可能由不同的团队开发,具有各自独特的接口和依赖关系。通过使用外观模式,我们可以将这些模块的接口整合成一个统一的接口,使得其他模块可以更加简洁、方便地访问它们。
  2. 隐藏复杂系统的实现细节:当一个系统的实现细节非常复杂时,我们可以使用外观模式来隐藏这些细节。通过提供一个简化的接口给客户端使用,我们可以保护系统的内部结构和实现细节不被外部直接访问和修改。这有助于确保系统的稳定性和安全性。
  3. 在分布式系统中整合服务:在分布式系统中,往往存在多个服务协同工作的情况。这些服务可能部署在不同的服务器上,具有各自独特的接口和通信协议。通过使用外观模式,我们可以将这些服务的接口整合成一个统一的接口,使得客户端可以更加简洁、方便地访问它们。这降低了客户端与分布式系统之间的通信复杂性和耦合度。

总结

外观模式是一种非常实用的设计模式,它通过引入一个统一的接口来隐藏系统的复杂性,使得客户端可以更方便地使用子系统。在实际应用中,我们应该根据具体的需求和场景来选择合适的设计模式,以提高软件系统的可维护性、可扩展性和可重用性。外观模式为我们提供了一个有效的手段来简化客户端的使用和降低系统的复杂性。

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

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

相关文章

书生浦语训练营2期-第二节课笔记作业

目录 一、前置准备 1.1 电脑操作系统:windows 11 1.2 前置服务安装(避免访问127.0.0.1被拒绝) 1.2.1 iis安装并重启 1.2.2 openssh安装 1.2.3 openssh服务更改为自动模式 1.2.4 书生浦语平台 ssh配置 1.3 补充(前置服务ok…

Thread的基本用法

目录 正文: 1.线程创建 2.线程休眠 3.获取线程实例 4.线程中断 5.线程等待join() 总结: 正文: 1.线程创建 线程创建是多线程编程的第一步,它涉及到创建一个可以并行执行的新线程。在Java中,有几种不同的方法可…

【Laravel】08 RESTful风格

【Laravel】08 视图模板动态渲染数据 1. RESTful风格 1. RESTful风格 (base) ➜ example-app php artisan make:model Blog -mc Model created successfully. Created Migration: 2024_04_01_143040_create_blogs_table Controller created successfully.(base) ➜ example-…

简述JMeter实现分布式并发及操作

为什么要分布式并发? JMeter性能实践过程中,一旦进行高并发操作时就会出现以下尴尬场景,JMeter客户端卡死、请求错误或是超时等,导致很难得出准确的性能测试结论。 目前知道的有两个方法可以解决JMeter支撑高并发: …

阿里 对象存储OSS 云存储服务

1.简介 对象存储服务(Object Storage Service ,OSS) 是一种 海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。 2.如何使用。参考文档 看文档,说的…

【python从入门到精通】-- 第四战:语句汇总

🌈 个人主页:白子寰 🔥 分类专栏:python从入门到精通,魔法指针,进阶C,C语言,C语言题集,C语言实现游戏👈 希望得到您的订阅和支持~ 💡 坚持创作博文…

docker从入门到熟悉

一、什么是docker? Docker是一个用于开发,交付和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助Docker,您可以以与管理应用程序相同的方式来管理基础架构。通过利用Docker的快速交付…

GPT3, llama2, InternLM2技术报告对比

GPT3(September 22, 2020)是大语言应用的一个milestone级别的作品,Llama2(February 2023)则是目前开源大模型中最有影响力的作品,InternLM2(2023.09.20)则是中文比较有影响力的作品。…

Linux文件搜索工具(gnome-search-tool)

opensuse下安装: sudo zypper install gnome-search-tool 操作界面:

JNews Theme最新版本:新闻网站首选的WordPress主题,功能强大且灵活

JNews Theme最新版本:新闻网站的首选WordPress主题 在当今数字化时代,新闻网站扮演着至关重要的角色。为了打造一个吸引读者、功能齐全的新闻平台,选择一款合适的WordPress主题显得尤为关键。而JNews Theme最新版本正是新闻网站的首选WordPr…

MacOS - brew 和 brew cask 有什么区别?

brew 是 ruby 的包管理,后来看 yangzhiping 的博客介绍了 brew cask,感觉 cask 是更好的关联关系管理,但是,我后来使用过程中,发现很多软件 brew cask 里没有,但是 brew 里面倒是挺多!今天来给说…

java面试题(Redis)

事情干的差不多了,开刷面试题和算法,争取在短时间内快速成长,理解java面试的常见题型 一、redis使用场景: 缓存:穿透、击穿、雪崩 双写一致、持久化 数据过期、淘汰策略 分布式锁:setnx、redisson 计数…

【JavaScript】函数 ⑦ ( 函数定义方法 | 命名函数 | 函数表达式 )

文章目录 一、函数定义方法1、命名函数2、函数表达式3、函数表达式示例 一、函数定义方法 1、命名函数 定义函数的标准方式 就是 命名函数 , 也就是之前讲过的 声明函数 ; 函数 声明后 , 才能被调用 ; 声明函数的语法如下 : function functionName(parameters) { // 函数体 …

计算机网络:数据链路层 - 可靠传输协议

计算机网络:数据链路层 - 可靠传输协议 可靠传输概念停止-等待协议 SW回退N帧协议 GBN选择重传协议 SR 可靠传输概念 如下所示,帧在传输过程中受到干扰,产生了误码。接收方的数据链路层,通过真伪中的真检验序列 FCS 字段的值&…

ROS 2边学边练(13)-- 创建一个功能包

前言 功能包是啥 简单理解,功能包就是一个文件夹,一个具备一定功能的文件夹,一个有组织有结构的文件夹,一个能方便分享给其他人使用的文件夹,比如我们的小海龟功能包,它就是一个文件夹,名字叫t…

WPS 不登录无法使用基本功能的解决办法

使用wps时,常常有个比较让人烦恼的事,在不登录的情况下,新建或者打开文档时,wps不让你使用其基本的功能,如设置字体等,相关界面变成灰色,这时Wps提示用户登录注册或登录,但我又不想登…

【QT入门】 无边框窗口设计之综合运用,实现WPS的tab页面

往期回顾: 【QT入门】 无边框窗口设计之实现窗口阴影-CSDN博客 【QT入门】 无边框窗口设计之实现圆角窗口-CSDN博客 【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口-CSDN博客 【QT入门】 无边框窗口设计之综合运用,实现WPS的tab页面 …

Nexus的docker安装,maven私服

文章目录 前言安装创建文件夹设置文件夹权限docker创建指令制作docker-compose.yaml文件 查看网站访问网页查看密码 前言 nexus作为私服的maven仓库,在企业级应用中,提供了依赖来源的稳定性,为构建庞大的微服务体系,打下基础 安…

算法——分治(快速排序)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享分治算法关于快速排序的专题 对于快速排序在我个人主页专栏 <排序> 有详细的介绍,此专题对快排进行了优化操作,并介绍了优化后的快排的几种运用 如果有不足的或者错误的请…

【正点原子探索者STM32F4】TFTLCD实验学习记录:FSMC控制 TFTLCD的寄存器配置

FSMC控制 TFTLCD的寄存器配置 异步模式 A控制 TFTLCDFSMC寄存器配置ILI9341电平持续时间要求 参考 异步模式 A控制 TFTLCD LCD以ILI9341为例 FSMC寄存器配置 对于异步突发访问方式&#xff0c; FSMC 主要设置 3 个时间参数&#xff1a;地址建立时间(ADDSET)、 数据 建立时间…