外观模式 (Facade Pattern)

定义:

外观模式(Facade Pattern)是一种结构型设计模式,它通过提供一个统一的高层接口来简化复杂子系统或库的访问。这种模式的关键在于,它创建了一个外观类,这个类封装了对子系统的一系列复杂交互,使得子系统更易于使用和理解。

外观模式的主要特点和目的包括:

  1. 简化复杂系统的接口:外观模式为复杂的内部子系统提供了一个简单的外部接口。这样,客户端在使用这些子系统时只需要与外观类交互,而不需要了解或直接访问系统的复杂内部工作。
  2. 降低子系统与客户端之间的耦合度:客户端通过外观类与子系统交互,减少了与子系统内部多个模块的直接依赖。这样做有助于减少客户端和子系统之间的耦合,使得系统更易于维护和扩展。
  3. 提高使用便利性:外观模式通过为复杂子系统提供一个简单明了的接口,使得客户端在使用这些系统时更加方便。
解决的问题:
  • 复杂子系统的简化接口:当一个系统变得非常复杂或难以理解时,外观模式提供了一个简单的接口,通过这个接口客户端可以更容易地访问和使用这个系统。
  • 客户端与子系统的解耦:在没有外观模式的情况下,客户端可能需要与多个子系统的多个组件直接交互,这会使客户端与子系统之间的耦合变得复杂。外观模式允许客户端通过一个单一的接口与子系统交互,从而降低耦合度。
  • 易于使用和维护:外观模式使子系统的使用变得更加简单直接,这不仅使得客户端代码变得更简洁,也使得维护更加容易,因为大部分依赖都集中在外观接口上。
  • 隐藏系统的复杂性:外观模式隐藏了其后的复杂子系统,这样客户端就不需要了解这些复杂性。这对于降低整体的复杂性、提高系统的可读性和可维护性非常有帮助。
  • 隔离变化:如果子系统经常更改,那么可以通过修改外观类来应对这些变化,从而避免直接影响到使用这些子系统的客户端。

总的来说,外观模式提供了一种方式来减少系统的复杂性,并为复杂子系统提供了一个简洁明了的界面,使子系统更易于使用和维护。

使用场景:
  • 简化复杂系统的访问
    • 当系统变得非常复杂或难以理解时,使用外观模式提供一个简化的接口,使系统更易于使用和理解。
  • 解耦系统和客户端代码
    • 如果你想要降低系统中不同层次或不同子系统之间的依赖关系,可以使用外观模式作为它们之间的中介。
  • 分层架构
    • 在多层架构的程序中,可以使用外观作为每一层的入口点,这样层与层之间的交互只通过这些外观进行,从而简化依赖关系。
  • 为复杂子系统提供统一接口
    • 当需要为复杂的子系统提供一个清晰简单的接口时,外观模式允许用户通过一个统一的界面与子系统交互。
  • 封装遗留代码或库
    • 对于旧系统或第三方库进行封装,以提供更清晰、更简单的接口,使得老系统或库更易于被应用程序使用。
  • 减少编译依赖
    • 外观模式可以将一个复杂子系统的依赖集中到一个单一的外观中,这样当子系统变化时,只影响到外观类,而不是所有依赖于子系统的代码。
  • 隔离代码
    • 当存在多个可能变化的依赖时,外观模式可以将这些依赖从客户端代码隔离出去,提高子系统的独立性和可移植性。

外观模式是一种简单却功能强大的模式,特别适合用于简化复杂系统,减少系统间的耦合,并提高代码的可维护性和可扩展性。

示例代码 1 - 简单外观模式:
// 子系统类
class SubSystemOne {void methodOne() {System.out.println("SubSystemOne Method");}
}class SubSystemTwo {void methodTwo() {System.out.println("SubSystemTwo Method");}
}class SubSystemThree {void methodThree() {System.out.println("SubSystemThree Method");}
}// 外观类
class Facade {private SubSystemOne one;private SubSystemTwo two;private SubSystemThree three;public Facade() {one = new SubSystemOne();two = new SubSystemTwo();three = new SubSystemThree();}void methodA() {one.methodOne();two.methodTwo();}void methodB() {two.methodTwo();three.methodThree();}
}
示例代码 2 - 使用外观模式简化接口:
// 复杂系统的各个组件
class CPU {void start() {System.out.println("CPU is starting.");}
}class Memory {void load() {System.out.println("Memory is loading.");}
}class HardDrive {void read() {System.out.println("Reading from hard drive.");}
}// 外观类
class ComputerFacade {private CPU cpu;private Memory memory;private HardDrive hardDrive;public ComputerFacade() {this.cpu = new CPU();this.memory = new Memory();this.hardDrive = new HardDrive();}public void startComputer() {cpu.start();memory.load();hardDrive.read();System.out.println("Computer started successfully.");}
}
主要符合的设计原则:
  1. 单一职责原则(Single Responsibility Principle):
    • 外观模式提供了一个统一的接口来访问子系统,这个接口的职责单一:封装子系统的复杂性并提供简单的接口。这样,子系统本身和外观之间的关注点是分开的。
  2. 开闭原则(Open-Closed Principle):
    • 外观模式使得客户端代码可以在不修改子系统的代码的情况下使用子系统。子系统可以独立于客户端和外观类变化和发展,只要外观的接口保持不变,客户端代码不需要做出任何改变。
  3. 最少知识原则(Principle of Least Knowledge)/迪米特法则(Law of Demeter):
    • 外观模式鼓励减少系统间的直接交互,客户端只需要知道外观接口,不需要了解子系统的内部实现细节,从而减少了系统间的依赖和耦合。

通过使用外观模式,可以将复杂的系统背后的复杂性隐藏起来,提供简单的接口,使得客户端代码更加清晰、易于理解和维护。同时,这种模式帮助维护系统各部分之间的独立性和可扩展性。

在JDK中的应用:
  • java.lang.Class:
    • java.lang.Class 类提供了对 Java 反射功能的高级封装。它隐藏了 Java 反射 API 的复杂性,允许用户以更简单的方式处理反射操作,例如获取类的方法、构造函数、成员变量等。
  • Java数据库连接(JDBC)API:
    • JDBC API 提供了简化数据库操作的接口,封装了底层的数据库访问细节。例如,java.sql.DriverManager 类提供了一个简化的方法来建立数据库连接。
  • java.net.URLjava.net.URLConnection:
    • 这些类提供了简化的方法来处理网络连接和数据传输。用户可以通过 URL 类的简单接口来访问和操作网络资源,而不需要深入了解底层网络通信的细节。
  • Java NIO Files API:
    • Java NIO中的 java.nio.file.Files 类提供了一系列静态方法,用于简化文件操作,如读取、写入、复制和移动文件。这些方法封装了文件操作的复杂性。

虽然在JDK中这些例子并不总是被标记为外观模式的经典应用,但它们确实遵循了外观模式的核心理念:提供简化的接口来隐藏底层的复杂性,使得复杂的操作对用户来说更加友好和易于使用。

在Spring中的应用:
  • Spring Web MVC的DispatcherServlet:
    • DispatcherServlet作为前端控制器(Front Controller),为Spring Web MVC提供了一个集中的请求处理机制。它封装了处理HTTP请求的复杂流程,如路由请求、调用控制器、返回响应等,简化了Web应用的开发。
  • Spring的JdbcTemplate:
    • JdbcTemplate是Spring提供的一个类,用于简化JDBC操作。它封装了创建连接、执行SQL语句、处理结果集等JDBC操作的复杂性,提供了一个更简洁和易用的接口。
  • Spring Security的配置类:
    • Spring Security的配置类,如WebSecurityConfigurerAdapter,提供了一种简化的方式来配置安全性相关的各种细节,如认证、授权等。它隐藏了安全性配置的复杂性,使开发者能够轻松地为应用程序添加安全性功能。
  • Spring Boot的自动配置:
    • Spring Boot的自动配置类似于外观模式的应用,它封装了Spring应用程序的常见配置,简化了Spring应用程序的配置过程。开发者只需少量配置或无需任何配置,即可运行起一个Spring应用程序。

这些例子展示了外观模式如何在Spring框架中实现,它通过提供简化的接口和抽象层,隐藏了底层复杂性,使得Spring框架的使用变得更简单、直观。


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

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

相关文章

【赠书第7期】从零基础到精通Flutter开发

文章目录 前言 1 安装Flutter和Dart 2 了解Flutter的基础概念 2.1 Widget 2.2 MaterialApp和Scaffold 2.3 Hot Reload 3 编写你的第一个Flutter应用 3.1 创建一个Flutter项目 3.2 修改默认页面 3.3 添加交互 4 深入学习Flutter高级特性 4.1 路由和导航 4.2 状态管…

python之TCP的网络应用程序开发

文章目录 版权声明python3编码转换socket类的使用创建Socket对象Socket对象常用方法和参数使用示例服务器端代码客户端代码 TCP客户端程序开发流程TCP服务端程序开发流程TCP网络应用程序注意点socket之send和recv原理剖析send原理剖析recv原理剖析send和recv原理剖析图 多任务版…

浅谈C#在unity应用中的工厂模式

文章目录 前言简单工厂模式工厂方法模式抽象工厂模式Unity实战 前言 工厂模式是一种创建型设计模式,它提供了一种将对象的实例化过程封装起来的方法,使得客户端代码不必直接依赖于具体类。这有助于降低代码的耦合度,提高代码的可维护性和可扩…

Python项目打包

Python项目如何打包? 本指南总结了Python项目打包的最佳实践,主要涉及代码的打包和分发,以及环境和依赖的管理。 0. 一般项目清单 源代码(可使用git托管)数据包(可使用DVC托管)Docker环境镜像…

Python进行threading多线程编程及高级并发处理机制

threading 模块是 Python 中用于进行多线程编程的标准库之一。通过 threading 模块,你可以创建和管理线程,使得程序能够并发执行多个任务。以下是一些基本的 threading 模块的用法: 1. 创建线程: 使用 threading.Thread 类可以创…

在两个java项目中实现Redis的发布订阅模式

如何在两个java项目中实现Redis的发布订阅模式? 1. Redis简介2. 发布订阅模式介绍3. 实现思路4. 代码实现及详细解释4.1. RedisUtil4.2. Publisher4.3. Subscriber4.4. 运行程序 目录: Redis简介发布订阅模式介绍实现思路代码实现及详细解释 1. Redis简…

HTB Napper WriteUp

Napper 2023年11月12日 14:58:35User Nmap ➜ Napper nmap -sCV -A -p- 10.10.11.240 --min-rate 10000 Starting Nmap 7.80 ( https://nmap.org ) at 2023-11-12 13:58 CST Nmap scan report for app.napper.htb (10.10.11.240) Host is up (0.15s latency). Not shown: …

gitee推荐-SAPI++

一下内容来自gitee。 SaaS-Apps-Engine: 智者|SAPI是多应用、多租户SaaS应用引擎,支持(小程序/公众号/轻应用/企微/抖音/支付宝/百度)等多平台应用。基于ThinkPHP6.1/8.0原生多应用模式开发,简洁、高效、易扩展。集成强大的权限控…

适用于电脑的5个免费文件恢复软件分享

适用于电脑的最佳免费文件恢复软件 任何计算机用户都可能经历过丢失重要文件的恐惧。重要数据的丢失可能会令人不安和沮丧,无论是由于不小心删除、计算机故障还是硬盘格式化造成的。幸运的是,在数字时代,您可以使用值得信赖的解决方案检索这些…

好工具|datamap,一个好用的地图可视化Excel插件,在Excel中实现地理编码、拾取坐标

在做VRP相关研究的时候,需要对地图数据做很多处理,比如地理编码,根据“重庆市沙坪坝区沙正街174号”这样的一个文本地址知道他的经纬度;再比如绘制一些散点图,根据某个位置的经纬度在地图上把它标注出来。还有有的时候…

vue + docxtemplater 导出 word 文档

一、痛点 word 导出 这种功能其实之前都是后端实现的,但最近有个项目没得后端。所以研究下前端导出。 ps: 前端还可以导出 pdf,但是其分页问题需要话精力去计算才可能实现,并且都不是很完善。可参考之前的文章:利用 h…

MIT6.824-Raft笔记:脑裂、Majority Vote(过半投票/过半选举)

本部分主要是问题引入,以及给出一个解决方案 1 脑裂(Split Brain) replication system的共同点:单点 前面几个容错特性(fault-tolerant)的系统,有一个共同的特点。 MapReduce复制了计算&…

JavaScript框架 Angular、React、Vue.js 的全栈解决方案比较

在 Web 开发领域,JavaScript 提供大量技术栈可供选择。其中最典型的三套组合,分别是 MERN、MEAN 和 MEVN。前端框架(React、Angular 和 Vue)进行简化比较。 MERN 技术栈详解 MERN 技术栈包含四大具体组件: MongoDB&am…

蓝桥杯物联网竞赛_STM32L071_3_Oled显示

地位: 对于任何一门编程语言的学习,print函数毫无疑问是一种最好的调试手段,调试者不仅能通过它获取程序变量的运行状态而且通过对其合理使用获取程序的运行流程,更能通过关键变量的输出帮你验证推理的正确与否,朴素的…

常见网络安全防护

1 阻断服务攻击(DOS) 阻断服务攻击,想办法目标网络资源用尽变种:分布式阻断服务攻击 影响: 宽带消耗性(消耗目标的带宽)资源消耗型(消耗目标的计算资源) 解决方案&am…

人工智能对网络安全的影响越来越大

如果问当前IT行业最热门的话题是什么,很少有人会回答除了人工智能(AI)之外的任何话题。 在不到 12 个月的时间里,人工智能已经从一项只有 IT 专业人员才能理解的技术发展成为从小学生到作家、程序员和艺术家的每个人都使用的工具…

MySQL索引事务基础

目录 1. 索引 1.1索引的概念 1.2索引的特点 1.3 索引的使用场景 1.4索引的使用 1.4.1查看索引 1.4.2创建索引 1.4.3删除索引 1.5索引保存的数据结构 2.事务 2.1经典例子 2.2事务的概念 2.3事务的使用 2.4事务的4个核心特性 2.5事务的并发问题 2.5.1脏读 2.5.2不可…

Python + Docker 还是 Rust + WebAssembly?

在不断发展的技术世界中,由大语言模型驱动的应用程序,通常被称为“LLM 应用”,已成为各种行业技术创新背后的驱动力。随着这些应用程序的普及,用户需求的大量涌入对底层基础设施的性能、安全性和可靠性提出了新的挑战。 Python 和…

Java项目如何打包成Jar(最简单)

最简单的办法,使用Maven插件(idea自带) 1.选择需要打包的mudule,点击idea右侧的maven插件 2.clean操作 3.选择需要的其他mudule,进行install操作(如果有) 4.再次选择需要打包的module&#…

Vue.observable 是什么

Observable 翻译过来我们可以理解成可观察的 Vue.js2.6 新增 Vue.observable,让一个对象变成响应式数据。Vue 内部会用它来处理 data 函数返回的对象 。 返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化…