设计模式之门面模式

news2024/11/18 11:21:34

前言

什么是门面模式

门面模式是一种结构型设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。它定义了一个高层接口,让子系统更容易使用。这种模式常用于将一个复杂的子系统封装成一个简单的接口,使得客户端可以方便地使用子系统的功能,而不需要了解子系统的具体实现细节。

门面模式的特点

  1. 代理模式能够隐藏真实对象的实现细节,使客户端无需知晓真实对象的工作方式和结构。
  2. 通过代理类来间接访问真实类,可以在不修改真实类的情况下对其进行扩展、优化或添加安全措施。
  3. 代理模式实现起来简单,易于扩展和维护,符合面向对象设计原则中的开闭原则。

门面模式的核心角色

门面模式(Facade Pattern)有三个核心角色:

  1. 门面角色(Facade):这是门面模式的核心,被客户角色调用。它熟悉子系统的功能,内部根据客户角色已有的需求预定了几种功能组合。
  2. 子系统角色(Subsystem):实现了子系统的功能。对于子系统角色来说,门面角色和客户角色都是未知的,它没有任何门面角色信息和链接。
  3. 客户角色(Client):这是使用门面模式的外部请求者,它通过门面角色来访问子系统,以获取所需的功能。

门面模式如何实现

假如用门面模式来模拟实现一下去饭店点菜吃饭应该怎么实现呢?虽然去饭店吃饭这件事挺普通的,但是要想吃到饭,起码是要走这样一个流程:点餐、炒菜、上菜、收/付钱。其实这里的饭店就可以看作是一个门面角色,饭店内不同的角色:如老板、收银员、服务员、厨师等,可以看作是饭店这个门面内的子系统角色,不同的角色职责是不同的,服务员负责帮客人点餐、上菜,厨师炒菜,收银员负责收钱,但是对于客人而言,吃饭是重点,通常不会关注是谁做的、谁端上来的。

那使用门面模式怎么实现呢?UML类图如下:

1、Restaurant:饭店类,有三个List类型的属性,分别用来表示饭店内会有厨师、服务员、收银员等不同角色的人员对象;对应还有三个可以给饭店增加三种不同角色人员的方法;最后一个方法就是饭店对外的主要职能:可以吃饭;

2、Waiter:服务员类,有两个方法:帮客人下单、上菜;

3、Cook:厨师类,有一个方法:炒菜;

4、Cashier:收银员类,有一个方法:收菜;

5、Cilent:客户端类,作为客户端,直接依赖Restaurant类,而不具体去找某个服务员或厨师;

/**
 * 服务员
 */
@Data
@AllArgsConstructor
public class Waiter {
    private String name;

    public void placeOrder(){
        System.out.println(this.name+"->帮客人点菜");
    }

    public void serveDishes(){
        System.out.println(this.name+"->给客人上菜");
    }
}
/**
 * 厨师
 */
@Data
@AllArgsConstructor
public class Cook {
    private String name;

    public void cooking() {
        System.out.println(this.name + "->炒菜");
    }
}
/**
 * 收银员
 */
@Data
@AllArgsConstructor
public class Cashier {
    private String name;

    public void collectMoney() {
        System.out.println(this.name + "->收钱");
    }
}
/**
 * 饭店
 */
 @Data
public class Restaurant {
    private String name;
    private List<Cook> cooks = new ArrayList<>();
    private List<Waiter> waiters = new ArrayList<>();
    private List<Cashier> cashiers = new ArrayList<>();

    public Restaurant(String name) {
        this.name = name;
    }

    public void addCooks(Cook cook) {
        this.cooks.add(cook);
    }

    public void addWaiter(Waiter waiter) {
        this.waiters.add(waiter);
    }

    public void addCashier(Cashier cashier) {
        this.cashiers.add(cashier);
    }

    private int ranomInt(Integer maxInt){
        Random random = new Random();
        return random.nextInt(maxInt);
    }
    public void eat(){
        this.waiters.get(this.ranomInt(this.waiters.size())).placeOrder();//点菜
        this.cooks.get(this.ranomInt(this.cooks.size())).cooking();//炒菜
        this.waiters.get(this.ranomInt(this.waiters.size())).serveDishes();//上菜
        System.out.println("客人->吃饭");
        this.cashiers.get(this.ranomInt(this.cashiers.size())).collectMoney();//收钱

    }
}
public class Client {
    public static void main(String[] args) {
        Restaurant restaurant = new Restaurant("和平饭店");
        Cook cook1 = new Cook("张厨师");
        Cook cook2 = new Cook("李厨师");
        restaurant.addCooks(cook1);
        restaurant.addCooks(cook2);
        Waiter waiter1 = new Waiter("王小红");
        Waiter waiter2 = new Waiter("张小月");
        restaurant.addWaiter(waiter1);
        restaurant.addWaiter(waiter2);
        Cashier cashier1 = new Cashier("老板");
        Cashier cashier2 = new Cashier("老板娘");
        restaurant.addCashier(cashier1);
        restaurant.addCashier(cashier2);
        restaurant.eat();
    }
}

门面模式的适用场景

门面模式适用于以下场景:

  1. 为一个复杂的子系统提供一个简单的接口,使得客户端可以方便地使用子系统的功能。
  2. 需要对一个子系统进行封装,并隐藏子系统的内部实现细节,只提供一个精简的接口供客户端使用,这样可以降低客户端与子系统的耦合度。
  3. 需要提高子系统的独立性,使得客户端不直接与子系统交互,而是通过门面角色来进行交互。
  4. 需要隔离客户端与子系统的直接交互,预防低水平人员带来的风险扩散。

总结

优点:

  1. 减少系统的相互依赖:门面模式可以让客户端只需要依赖门面对象,而与子系统无关。这样可以降低系统耦合度。
  2. 提高灵活性:通过门面角色,客户端不再直接与子系统交互,而是通过门面角色提供的精简接口来实现交互。这样,子系统的内部实现细节可以被隐藏起来,子系统如何变化对客户端来说是透明的,提高了系统的灵活性。
  3. 提高安全性:外部只能通过门面访问子系统的功能,门面没有开放的就不能访问,提高了子系统的安全性。

缺点:

  1. 不符合开闭原则。系统投产后,一旦发现错误,只能修改门面角色的代码,风险比较大。
  2. 系统的复杂性和理解难度有一定增加;

总的来说,门面模式可以简化复杂子系统的使用、隐藏实现细节、提高子系统独立性和隔离客户端与子系统的直接交互,但也存在一些缺点需要注意。在具体使用时,需要根据具体情况进行权衡,并考虑是否适合使用该模式。

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

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

相关文章

如何使用navicat图形化工具远程连接MariaDB数据库【cpolar内网穿透】

公网远程连接MariaDB数据库【cpolar内网穿透】 文章目录 公网远程连接MariaDB数据库【cpolar内网穿透】1. 配置MariaDB数据库1.1 安装MariaDB数据库1.2 测试局域网内远程连接 2. 内网穿透2.1 创建隧道映射2.2 测试随机地址公网远程访问3. 配置固定TCP端口地址3.1 保留一个固定的…

记 : CTF2023羊城杯 - Reverse 方向 Blast 题目复现and学习记录

文章目录 前言题目分析and复习过程exp 前言 羊城杯题目复现&#xff1a; 第一题 知识点 &#xff1a;DES算法 &#xff1a; 链接&#xff1a;Ez加密器 第二题 知识点 &#xff1a;动态调试 &#xff1a; 链接&#xff1a;CSGO 这一题的查缺补漏&#xff1a; 虚假控制流的去除…

CVE-2021-44228 Apache log4j 远程命令执行漏洞

一、漏洞原理 log4j(log for java)是由Java编写的可靠、灵活的日志框架&#xff0c;是Apache旗下的一个开源项目&#xff0c;使用Log4j&#xff0c;我们更加方便的记录了日志信息&#xff0c;它不但能控制日志输出的目的地&#xff0c;也能控制日志输出的内容格式&#xff1b;…

算法通过村第十二关青铜挑战——不简单的字符串转换问题

大家好&#xff0c;我是怒码少年小码。 今天练习一道数据处理的题目&#xff0c;字符串->整数 int myAtoi(string s) {unsigned long len s.length();//去除前端空格int index 0;while(index < len ){if(s[index]! ){break;}index;}if(index len){return 0;}int sign…

VsCode配置C/C++环境、控制台中文乱码、中文包不生效、debug调试、cin无法输入

VsCode配置C/C环境 文章目录 VsCode配置C/C环境[toc]下载VScode下载编译器MinGW 并解压将MinGW添加至环境变量测试MingGW 环境变量配置成功安装插件重启 VSCODE 并创建编程文件测试 debug可能遇到的问题Chinese 中文包未生效外部控制台中文乱码cin 无法输入终端中文乱码 下载VS…

cmake练习一

需求&#xff1a; 1、利用CGAL库Boost库&#xff0c;写一个关于CGAL的程序 2、使用cmake构建 1、创建目录结构 src中有一个main.cpp&#xff0c;放的是我们的主程序代码 2、安装CGAL和Boost库 略 3、编写cmakelist.txt cmake_minimum_required(VERSION 3.1.0) project(cg…

MySQL:至少参与xxx参与的全部事件

MySQL&#xff1a;至少参与xxx参与的全部事件 – WhiteNights Site 标签&#xff1a;MySQL, 数据库 这玩意&#xff0c;期末要考&#xff0c;还是重点。所以不得不仔细思考思考怎么写了。 什么时候用NOT EXISTS 双重否定表肯定 之前虽然已经讲过了&#xff0c;不过那一篇文章…

Apache ActiveMQ RCE漏洞复现(CNVD-2023-69477)

0x01 产品简介 ActiveMQ是一个开源的消息代理和集成模式服务器&#xff0c;它支持Java消息服务(JMS) API。它是Apache Software Foundation下的一个项目&#xff0c;用于实现消息中间件&#xff0c;帮助不同的应用程序或系统之间进行通信。 0x02 漏洞概述 Apache ActiveMQ 中存…

Flink on yarn 加载失败plugins失效问题解决

Flink on yarn 加载失败plugins失效问题解决 flink版本&#xff1a;1.13.6 1. 问题 flink 任务运行在yarn集群,plugins加载失效,导致通过扩展资源获取任务参数失效 2. 问题定位 yarn容器的jar包及插件信息,jar包是正常上传 源码定位 加载plugins入口&#xff0c;TaskMana…

Go学习第十章——文件操作,Json和测试

Go文件操作&#xff0c;Json和测试 1 文件1.1 基本介绍1.2 读取的基本操作1.3 写入的基本操作1.4 使用案例(三个) 2 Go语言的Json使用2.1 序列化案例2.2 反序列化案例 3 单元测试3.1 先看个需求3.2 快速入门3.3 入门总结 1 文件 1.1 基本介绍 文件在程序中是以流的形式来操作…

Android环境变量macOS环境变量配置

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览macOS基础知识 三、设置环境变量3.1 终…

【iOS免越狱】利用IOS自动化web-driver-agent_appium-实现自动点击+滑动屏幕

1.目标 在做饭、锻炼等无法腾出双手的场景中&#xff0c;想刷刷抖音 刷抖音的时候有太多的广告 如何解决痛点 抖音自动播放下一个视频 iOS系统高版本无法 越狱 安装插件 2.操作环境 MAC一台&#xff0c;安装 Xcode iPhone一台&#xff0c;16 系统以上最佳 3.流程 下载最…

Android Studio 导出 jar

AS版本&#xff1a;Android Studio Giraffe | 2022.3.1 Patch 1 1、File——New Module——Android Library 2、mylibrary——main——新建功能类 3、mylibrary——build.gradle——android {}内复制以下代码——Sync Now //Copy类型 tasks.register(makeJar, Copy) { //删…

Python深度学习实战-基于tensorflow原生代码搭建BP神经网络实现分类任务(附源码和实现效果)

实现功能 前面两篇文章分别介绍了两种搭建神经网络模型的方法&#xff0c;一种是基于tensorflow的keras框架&#xff0c;另一种是继承父类自定义class类&#xff0c;本篇文章将编写原生代码搭建BP神经网络。 实现代码 import tensorflow as tf from sklearn.datasets import…

[推荐]Linux安装与配置虚拟机之虚拟机服务器坏境配置

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 一.操作系统 1. 简介 操作系统&#xff08;perating System&#xff0c;简称OS&#xff09;是一种系统软件…

测试C#调用Vlc.DotNet组件播放视频

除了Windows Media Player组件&#xff0c;在百度上搜索到还有不少文章介绍采用Vlc.DotNet组件播放视频&#xff0c;关于Vlc.DotNet的详细介绍见参考文献1&#xff0c;本文学习Vlc.DotNet的基本用法。   VS2022中新建基于.net core的winform程序&#xff0c;在Nuget包管理器中…

Qt+JSON简单例子

QtJSON简单例子 QtJSONexample2参考 QtJSON #include "mainwindow.h" #include "ui_mainwindow.h" #include <QtDebug> #include <QJsonObject> #include <QJsonArray> #include <QJsonDocument> #include <QTextCodec> #i…

MarkDown详细入门笔记

本帖整理了MarkDown的入门学习笔记~ 一.介绍 Markdown 是一种轻量级的「标记语言」&#xff0c;它的优点很多&#xff0c;目前也被越来越多的写作爱好者&#xff0c;撰稿者广泛使用。 诸如微信公众平台、CSDN博客、还有Typora中写文档的部分&#xff0c;均涉及到MD的功能~ 它…

【rust/esp32】wsl2开发环境搭建与测试

文章目录 说在前面流程可能的问题wsl2相关rust相关vscode相关build相关 测试吐槽参考 说在前面 esp型号&#xff1a;esp32s3开发环境&#xff1a;wsl2rustc版本&#xff1a;rustc 1.73.0-nightlyesp idf版本&#xff1a;v5.1.1 流程 目前是按照这个demo的流程可以跑通修改demo…

【spark客户端】Spark SQL CLI详解:怎么执行sql文件、注释怎么写,支持的文件路径协议、交互式模式使用细节

文章目录 一. Spark SQL Command Line Options(命令行参数)二. The hiverc File1. without the -i2. .hiverc 介绍 三. 支持的路径协议四. 支持的注释类型五. Spark SQL CLI交互式命令六. Examples1. running a query from the command line2. setting Hive configuration vari…