【设计模式】JAVA Design Patterns——Facade(外观模式)

news2025/2/24 10:10:02

🔍目的


为一个子系统中的一系列接口提供一个统一的接口。外观定义了一个更高级别的接口以便子系统更容易使用。

🔍解释


真实世界例子

一个金矿是怎么工作的?“嗯,矿工下去然后挖金子!”你说。这是你所相信的因为你在使用一个金矿对外提供的一个简单接口,在内部它要却要做很多事情。这个简单的接口对复杂的子系统来说就是一个外观。

通俗描述

外观模式为一个复杂的子系统提供一个简单的接口。

维基百科

外观是为很大体量的代码(比如类库)提供简单接口的一种对象。

程序示例

使用上面金矿的例子。这里我们有矮人的矿工等级制度。


@Slf4j
public abstract class DwarvenMineWorker {

    public void goToSleep() {
        LOGGER.info("{} goes to sleep.", name());
    }

    public void wakeUp() {
        LOGGER.info("{} wakes up.", name());
    }

    public void goHome() {
        LOGGER.info("{} goes home.", name());
    }

    public void goToMine() {
        LOGGER.info("{} goes to the mine.", name());
    }

    private void action(Action action) {
        switch (action) {
            case GO_TO_SLEEP -> goToSleep();
            case WAKE_UP -> wakeUp();
            case GO_HOME -> goHome();
            case GO_TO_MINE -> goToMine();
            case WORK -> work();
            default -> LOGGER.info("Undefined action");
        }
    }

    public void action(Action... actions) {
        Arrays.stream(actions).forEach(this::action);
    }

    public abstract void work();

    public abstract String name();

    enum Action {
        GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
    }
}

@Slf4j
public class DwarvenTunnelDigger extends DwarvenMineWorker {

    @Override
    public void work() {
        LOGGER.info("{} creates another promising tunnel.", name());
    }

    @Override
    public String name() {
        return "Dwarven tunnel digger";
    }
}

@Slf4j
public class DwarvenGoldDigger extends DwarvenMineWorker {

    @Override
    public void work() {
        LOGGER.info("{} digs for gold.", name());
    }

    @Override
    public String name() {
        return "Dwarf gold digger";
    }
}

@Slf4j
public class DwarvenCartOperator extends DwarvenMineWorker {

    @Override
    public void work() {
        LOGGER.info("{} moves gold chunks out of the mine.", name());
    }

    @Override
    public String name() {
        return "Dwarf cart operator";
    }
}

创建外观类来进行操纵这些矿工:

public class DwarvenGoldmineFacade {

  private final List<DwarvenMineWorker> workers;

  public DwarvenGoldmineFacade() {
      workers = List.of(
            new DwarvenGoldDigger(),
            new DwarvenCartOperator(),
            new DwarvenTunnelDigger());
  }

  public void startNewDay() {
    makeActions(workers, DwarvenMineWorker.Action.WAKE_UP, DwarvenMineWorker.Action.GO_TO_MINE);
  }

  public void digOutGold() {
    makeActions(workers, DwarvenMineWorker.Action.WORK);
  }

  public void endDay() {
    makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP);
  }

  private static void makeActions(Collection<DwarvenMineWorker> workers,
      DwarvenMineWorker.Action... actions) {
    workers.forEach(worker -> worker.action(actions));
  }
}

使用外观:

DwarvenGoldmineFacade facade = new DwarvenGoldmineFacade();
facade.startNewDay();
// Dwarf gold digger wakes up.
// Dwarf gold digger goes to the mine.
// Dwarf cart operator wakes up.
// Dwarf cart operator goes to the mine.
// Dwarven tunnel digger wakes up.
// Dwarven tunnel digger goes to the mine.
facade.digOutGold();
// Dwarf gold digger digs for gold.
// Dwarf cart operator moves gold chunks out of the mine.
// Dwarven tunnel digger creates another promising tunnel.
facade.endDay();
// Dwarf gold digger goes home.
// Dwarf gold digger goes to sleep.
// Dwarf cart operator goes home.
// Dwarf cart operator goes to sleep.
// Dwarven tunnel digger goes home.
// Dwarven tunnel digger goes to sleep.

🔍类图


🔍适用性


使用外观模式

  • 你想为一个复杂的子系统提供一个简单的接口。随着子系统的发展,它们通常会变得更加复杂。多数模式在应用时会导致更多和更少的类。这使子系统更可重用,更易于自定义,但是对于不需要自定义它的客户来说,使用它也变得更加困难。 外观可以提供子系统的简单默认视图,足以满足大多数客户端的需求。只有需要更多可定制性的客户才需要查看外观外的东西(原子系统提供的接口)。
  • 客户端与抽象的实现类之间存在许多依赖关系。 引入外观以使子系统与客户端和其他子系统分离,从而提高子系统的独立性和可移植性。
  • 您想对子系统进行分层。 使用外观来定义每个子系统级别的入口点。 如果子系统是相关的,则可以通过使子系统仅通过其外观相互通信来简化它们之间的依赖性。

🔍Ending

Facade模式通常涉及一个名为Facade的单一类,该类提供了一个高级接口,用于与客户端交互,并将客户端的请求委派给系统内部的一组相关对象。这样,客户端就不需要直接与系统内部的各个组件进行交互,而是通过Facade来简化交互过程。 


希望本文能够帮助读者更深入地理解外观模式,并在实际项目中发挥其优势。谢谢阅读!


希望这份博客草稿能够帮助到你。如果有其他需要修改或添加的地方,请随时告诉我。

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

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

相关文章

先进的无人机GPS/GNSS模块解决方案

由于多星座支持和增强的信号接收能力&#xff0c;先进的GNSS模块提供了更高的精度和可靠性。集成传感器融合补偿信号中断&#xff0c;实现无缝导航。内置实时运动学(RTK)支持提供厘米级的定位精度。这些模块还优先考虑低功耗和紧凑的尺寸&#xff0c;确保更长的飞行时间和对无人…

第四范式Q1业务进展:驰而不息 用科技锻造不朽价值

5月28日&#xff0c;第四范式发布今年前三个月的核心业务进展&#xff0c;公司坚持科技创新&#xff0c;业务稳步拓展&#xff0c;用人工智能为千行万业贡献价值。 今年前三个月&#xff0c;公司总收入人民币8.3亿元&#xff0c;同比增长28.5%&#xff0c;毛利润人民币3.4亿元&…

Vue3项目练习详细步骤(第四部分:文章管理页面模块)

文章列表查询 页面主体结构 接口文档 接口调用 添加文章列表 添加组件 富文本编辑器 封面图片上传 接口文档 接口调用 编辑文章列表 结构调整 数据回显 接口文档 绑定请求数据 删除文章列表 接口文档 绑定请求数据 文章列表查询 页面主体结构 在ArticleManag…

太速科技-基于3U VPX 4核8线程I7 X86主板

基于3U VPX 4核8线程I7 X86主板 一、产品概述 该产品是一款基于第六代Intel i7四核八线程处理器的高性能3U VPX刀片式计算机。产品提供了4个x4 PCIe 3.0总线接口&#xff0c;其中2个x4 PCIe 3.0接口可配置为1个x8 PCIe3.0接口&#xff0c;另外2个x4 PCIe 3.0接口可灵活配置…

微信小程序教程DAY3

box标签 第二种方法 绿色第一种 第一种更好 效果一样 完成这个项目 先写循环

Git基本使用教程(学习记录)

参考文章链接&#xff1a; Git教程&#xff08;超详细&#xff0c;一文秒懂&#xff09; RUNOOB Git教程 Git学习记录 1Git概述 1.1版本控制软件功能 版本管理&#xff1a;更新或回退到历史上任何版本&#xff0c;数据备份共享代码&#xff1a;团队间共享代码&#xff0c;…

mirth Connect 自定义JAVA_HOME

mirth Connect 自定义JAVA_HOME 1、背景 服务器上安装了两个不同版本的Java&#xff0c;我希望Mirth服务使用与默认系统不同的版本。自定义指定java版本 2、解决方法 2.1 优先级说明 系统变量JAVA_HOME (设置后&#xff0c;mirth会根据这个进行启动运行服务&#xff0c;优先级…

2020 6.s081——Lab2:system calls

左岸的一座白色环形阶梯 浪人正在用和弦练习忧郁 晨曦下的少女听着吉他旋律 在许愿池边巴洛克式的叹息 ——许愿池的希腊少女 完整代码见&#xff1a;SnowLegend-star/6.s081 at syscall (github.com) System call tracing (moderate) 这个实验要求我们跟踪系统调用。 感觉实…

软件设计师,下午题 ——试题六

模型图 简单工厂模式 工厂方法模式抽象工厂模式生成器模式原型模式适配器模式桥接模式组合模式装饰&#xff08;器&#xff09;模式亨元模式命令模式观察者模式状态模式策略模式访问者模式中介者模式 简单工厂模式 工厂方法模式 抽象工厂模式 生成器模式 原型模式 适配器模式 桥…

nodemcu32s 和 mini D1 组局域网并用 webSocket 通信

实现思路 使用 mini D1 来搭建一个 webSocket 服务&#xff0c;然后使用 nodemcu32 连接&#xff0c;然后就可以进行通信了。 服务端代码&#xff08;mini D1&#xff09; 在代码中主要是需要控制好 loop 函数中的延时&#xff0c;也就是最后一行代码 delay&#xff0c;如果…

大模型时代的具身智能系列专题(六)

UCSD 王小龙组 王小龙是UCSD电子与计算机工程系的助理教授。他曾在加州大学伯克利分校与Alexei Efros和Trevor Darrell一起担任博士后研究员&#xff0c;在CMU RI获得了机器人学博士学位&#xff0c;师从Abhinav Gupta。他的研究重点是通过视频和物理机器人交互数据来学习3D和…

【AIGC】大型语言模型在人工智能规划领域模型生成中的探索

大型语言模型在人工智能规划领域模型生成中的新应用 一、引言二、LLM在规划领域模型生成中的潜力三、实证分析&#xff1a;LLM在规划领域模型生成中的表现四、代码实例&#xff1a;LLM在规划领域模型生成中的应用五、结论与展望 一、引言 随着人工智能技术的迅猛发展&#xff0…

yolov5-ros模型结合zed2相机部署在 Ubuntu系统

前言 本篇文章主要讲解yolov5-ros模型结合zed2相机进行实时检测&#xff0c;经改进实现了红绿灯检测&#xff0c;并输出检测类别与置信度&#xff01; 目录 一、环境配置二、zed2驱动安装三、yolov5-ros功能包配置四、运行官方权重文件四、运行自己权重文件 一、环境配置 1、…

分享6个打开就能让人眼前一亮的网站,每次浏览都像发现新大陆~

1、ZLibrary zh.zlibrary-be.se/ ZLibrary是一个广受欢迎的在线图书馆&#xff0c;它提供了一个庞大的电子书和文章资源库&#xff0c;数量超过千万。这个平台覆盖了国内外众多领域的电子书资源&#xff0c;几乎可以满足用户98%以上的搜索需求&#xff0c;无论是学术研究、文…

Netty中半包粘包的产生与处理:短连接、固定长度、固定分隔符、预设长度;redis、http协议举例;网络数据的发送和接收过程

目录 粘包、半包 相关概念 网络数据发送和接收过程 Netty半包粘包解决方案 ByteBuf获取和默认大小 短链接 固定长度 固定分隔符 预设长度 常见协议代码举例 redis协议 http协议 参考链接 粘包、半包 相关概念 程序处理过程中我们会通过缓冲区接收数据&#xff0c…

input输入框的一些复习

<template><div><div style"text-align: center;margin: 10px 0;"><span style"font-size: 15px;font-weight: bold;">input输入框的基本应用</span></div><el-descriptions :column"3" size"defau…

Golang dlv远程debug

1. 前期准备 1.1. dlv安装 1.1.1. go install安装 go install github.com/go-delve/delve/cmd/dlvlatest1.1.2. 手动安装 下载 linuxx86 架构 二进制文件 &#x1f4ce;dlv.linux.x86.zip zip文件&#xff0c;下载后&#xff08; 如果没权限&#xff0c;记得 执行chmod ax…

linux下使用cmake-gui编译WXQT

一.编译环境 操作系统&#xff1a;Ubuntu 22.04.3 LTS wxWidgets源码&#xff1a;wxWidgets-3.1.5 编译工具&#xff1a;CMake-gui qt版本&#xff1a;5.13.2 二.编译步骤 1.将源码解压。 2.打开CMake-gui&#xff0c;并设置好源码目录和构建目录 3.点击configure 会弹出…

【c++入门】this指针

this指针引出&#xff1a; 我们知道一个类可以有多个实例化对象&#xff0c;但是这多个实例化对象所调用的成员函数是在公共代码区&#xff1b; 我们先来定义一个Date类&#xff1a; class Date { public:void init(int year, int month, int day){_year year;_month month;…

excel怎么对非数字求和汇总?

如&#xff1a;学生小王的成绩为&#xff1a;A&#xff0c;A&#xff0c;A&#xff0c;A&#xff0c;B&#xff0c;B-……想得到的成绩汇总求和为&#xff1a;2A,2A,1B,1B- 如果在低版本里&#xff0c;用公式计算可能相当复杂&#xff0c;但是有了TEXTJOIN函数和UNIQUE函数&…