外观模式介绍

目录

一、外观模式介绍

1.1 外观模式定义

1.2 外观模式原理

1.2.1 外观模式类图

1.2.2 模式角色说明

1.2.3 示例代码

二、外观模式的应用

2.1 需求说明

2.2 需求实现

2.2.1 类图

2.2.2 具体实现

2.2.2.1 灯光类

2.2.2.2 电视类

2.2.2.3 空调类

2.2.2.4 外观面板类

2.2.2.5 测试类

三、外观模式总结

3.1 外观模式的优点

3.2 外观模式的缺点

3.3 外观模式的使用场景


一、外观模式介绍

1.1 外观模式定义

外观模式( Facade Pattern),也叫门面模式, 外观模式的原始定义是:为子系统中的一组接口提供统一的接口。它定义了一个更高级别的接口,使子系统更易于使用。
外观模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
门面模式有点类似之前讲到的迪米特法则(最少知识原则)和接口隔离原则:两个有交互的系统,只暴露有限的必要的接口。

门面类充当了系统中的"服务员",它为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互,如果没有门面类,每个客户类需要和多个子系统之间进行复杂的交互,系统的耦合度将会很大。

1.2 外观模式原理

1.2.1 外观模式类图

1.2.2 模式角色说明

外观(Facade)模式包含以下主要角色:

  • 外观(Facade)角色:

为多个子系统对外提供一个共同的接口。外观角色中可以知道多个相关的子系统中的功能和责任。在正常情况下,它将所有从客户端发来的请求委派到相应的子系统,传递给相应的子系统对象处理。

  • 子系统(Sub System)角色:

实现系统的部分功能,客户可以通过外观角色访问它。每一个子系统可以是一个类也可以是多个类的集合。每一个子系统都可以被客户端直接调用,或者被外观角色调用。子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另一个客户端而已。

1.2.3 示例代码

package main.java.cn.test.Facade.V1;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:17:07
 * @description 业务类A
 */
public class SubSystemA {
    public void methodA(){
       System.out.println("执行methodA()"+" =======");
    }
}

package main.java.cn.test.Facade.V1;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:19:02
 * @description 业务类B
 */
public class SubSystemB {
    public void methodB(){
        System.out.println("执行methodB()"+" =======");
    }
}

package main.java.cn.test.Facade.V1;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:19:29
 * @description 业务类C
 */
public class SubSystemC {
    public void methodC(){
        System.out.println("执行methodC()"+" =======");
    }
}

package main.java.cn.test.Facade.V1;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:20:21
 * @description 门面类
 */
public class Facade {
    private SubSystemA obj1 = new SubSystemA();
    private SubSystemB obj2 = new SubSystemB();
    private SubSystemC obj3 = new SubSystemC();

    public void method() {
        obj1.methodA();
        obj2.methodB();
        obj3.methodC();
    }
}

package main.java.cn.test.Facade.V1;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:20:53
 * @description 测试类
 */
public class Test {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.method();
    }
}

二、外观模式的应用

2.1 需求说明

智能家电控制。通过智能音箱来控制室内的灯、电视、空调.本来每个设备都需要进行独立的开关操作,现在通过智能音箱完成对这几个设备的统一控制。

2.2 需求实现

2.2.1 类图

2.2.2 具体实现

2.2.2.1 灯光类
package main.java.cn.test.Facade.V2;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:27:24
 * @description 灯光类
 */
public class Light {
    public void on() {
        System.out.println("打开灯......");
    }

    public void off() {
        System.out.println("关闭灯......");
    }

}

2.2.2.2 电视类
package main.java.cn.test.Facade.V2;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:27:54
 * @description 电视类
 */
public class TV {
    public void on() {
        System.out.println("打开电视......");
    }

    public void off() {
        System.out.println("关闭电视......");
    }
}

2.2.2.3 空调类
package main.java.cn.test.Facade.V2;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:28:27
 * @description 空调类
 */
public class AirCondition {
    public void on() {
        System.out.println("打开空调......");
    }

    public void off() {
        System.out.println("关闭空调......");
    }

}

2.2.2.4 外观面板类
package main.java.cn.test.Facade.V2;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:29:36
 * @description 外观面板类
 */
public class SmartAppliancesFacade {
    private Light light;
    private TV tv;
    private AirCondition airCondition;

    public SmartAppliancesFacade() {
        this.light = new Light();
        this.tv = new TV();
        this.airCondition = new AirCondition();
    }

    public void say(String message) {
        if (message.contains("打开")) {
            on();
        } else if (message.contains("关闭")) {
            off();
        } else {
            System.out.println("对不起没有听清楚您说什么! 请重新再说一遍");
        }
    }

    //起床后 语音开启 电灯 电视 空调
    private void on() {
        System.out.println("起床了!");
        light.on();
        tv.on();
        airCondition.on();
    }

    //睡觉前 语音关闭 电灯 电视 空调
    private void off() {
        System.out.println("睡觉了!");
        light.off();
        tv.off();
        airCondition.off();
    }

}

2.2.2.5 测试类
package main.java.cn.test.Facade.V2;

/**
 * @author ningzhaosheng
 * @date 2024/1/14 13:33:16
 * @description 测试类
 */
public class Test {
    public static void main(String[] args) {
        //创建外观对象
        SmartAppliancesFacade facade = new
                SmartAppliancesFacade();
        facade.say("打开家电");
        facade.say("关闭家电");
    }
}

三、外观模式总结

3.1 外观模式的优点

  1. 它对客户端屏蔽了子系统组件,减少了客户端所需要处理的对象数目,并使子系统使用起来更加的容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少。
  2. 它实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
  3. 一个子系统的修改对其他子系统没有任何影响,而子系统内部变化也不会影响到外观对象。

3.2 外观模式的缺点

  1. 不能很好的控制客户端直接使用子系统类,如果客户端访问子系统类做太多的限制则减少了可变性和灵活性。
  2. 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。

3.3 外观模式的使用场景

  • 简化复杂系统。

比如,当我们开发了一整套的电商系统后(包括订单、商品、支付、会员等系统),我们不能让用户依次使用这些系统后才能完成商品的购买,而是需要一个门户网站或手机 App 这样简化过的门面系统来提供在线的购物功能。

  • 减少客户端处理的系统数量。

比如,在 Web 应用中,系统与系统之间的调用可能需要处理 Database 数据库、Model 业务对象等,其中使用
Database 对象就需要处理打开数据库、关闭连接等操作,然后转换为Model 业务对象,实在是太麻烦了。如果能够创建一个数据库使用的门面(其实就是常说的 DAO 层),那么实现以上过程将变得容易很多。

  • 让一个系统(或对象)为多个系统(或对象)工作。

比如,线程池ThreadPool 就是一个门面模式,它为系统提供了统一的线程对象的创建、销毁、使用等。

  • 联合更多的系统来扩展原有系统。

当我们的电商系统中需要一些新功能时,比如,人脸识别,我们可以不需要自行研发,而是购买别家公司的系统
来提供服务,这时通过门面系统就能方便快速地进行扩展。

  • 作为一个简洁的中间层。

门面模式还可以用来隐藏或者封装系统中的分层结构,同时作为一个简化的中间层来使用。比如,在秒杀、库存、钱包等场景中,我们需要共享有状态的数据时(如商品库存、账户里的钱),在不改变原有系统的前提下,通过一个中间的共享层(如将秒杀活动的商品库存总数统一放在 Redis 里),就能统一进行各种服务(如,秒杀详情页、商品详情页、购物车等)的调用。

好了,本次分享就到这里,欢迎大家继续阅读《设计模式》专栏其他设计模式内容,如果有帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计----SSH实现的一个宠物商城

项目介绍 本项目分为前后台,分为管理员与用户两种角色,普通用户登录前台,管理员登录后台; 管理员角色包含以下功能: 管理员登录,用户管理,管理商品,商品分类管理,订单管理,留言管理,公告管理,新闻管理等功能。 用户…

MySQL索引创建原则和失效问题

一.索引创建原则 数据量较大,且查询比较频繁的表常作为查询条件、分组、排序的字段字段内容区分度高内容较长,使用前缀索引尽量创建联合索引要控制索引的数量如果索引列不能存储NULL值,请在创建表示使用NOT NULL约束它 二.索引失效 违反最左前缀法则范围查询右边的列,不能使用…

Linux文件同步

Linux文件同步 scp简介基本用法 rsync简介基本用法 tftp简介基本用法 其他命令ftpsftplftp 此博客将主要介绍Linux文件同步常用的两种命令:scp(secure copy)、rsync(remote synchronization)和tftp(Trivial…

k8s源码阅读:Informer源码解析

写在之前 Kubernetes的Informer机制是一种用于监控资源对象变化的机制。它提供了一种简化开发者编写控制器的方式,允许控制器能够及时感知并响应 Kubernetes 集群中资源对象的变化。Informer通过与Kubernetes API服务器进行交互,通过监听API服务器上资源…

计算机毕业设计 | SpringBoot宠物店管理系统(附源码)

1,绪论 项目背景 我国已经成为世界第二大经济体,经济实力高速发展以及百姓生活水平的普遍提高,不断地要求企业提供更加多元化的娱乐方式,更加快速和方便的服务,因此对宠物行业也提出了更加严格的要求,如管…

layabox_2d游戏A*寻路实践

使用工具 Red Blob Games 效果 项目地址 LayaAStar2D: Laya2.0引擎2D游戏使用AStar实践。

C++设计模式-- 2.代理模式 和 外观模式

文章目录 代理模式外观模式角色和职责代码演示一:代码演示二:外观模式适用场景 代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合 或不能直接引用另一个对象,而代…

<蓝桥杯软件赛>零基础备赛20周--第13周--DFS剪枝

报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周。 在QQ群上答疑&#x…

docker安装nacos+mysql+配置网络

一、配置网络 为什么要配置网络?因为 Nacos 内要连接MySQL数据库的,我的 MySQL 数据库也是用 Docker启动的,所以2个容器间要通信是需要配置他们使用相同的网络。这个操作要在启动Nacos容器之前。 注意:这里配置的网络只在镜像内部…

zabbix6.4设置网络设备端口流量P95

P95概念: p95函数写法: 需要监控P95的设备如下: 先找到原来的端口接收发送速率的监控项: 可以看到他们归属于自动发现规则:端口表UP 找到自动发现规则: 点击创建监控项原型: 公式如下&#xff…

基于LLM大模型的信息提取指南

信息提取(information Extraction)是从文本或文档集合中自动检索与特定主题相关的特定信息的过程。 这通常涉及自然语言处理技术的使用。 使用自然语言处理来提取信息通常会导致构建复杂的逻辑,这些逻辑有时非常具体并且不能很好地概括。 好…

Linux例行性工作 at和crontab命令

1,例行性工作 例行性工作 —— 在某一时刻,必须要做的事情 —— 定时任务 (比如:闹钟) 例行性工作分为两种:“单一的例行性工作 at”和“循环的例行性工作 crontab” 2,单一执行的例行性工作 …

C 程序运行机制

1.编辑 编写C语言源程序代码,源程序文件以“.c”作为扩展名。 2.编译 将C语言源程序转换为目标程序(或目标文件)。如果程序没有错误,没有任何提示,就会生成一个扩展名为“.obj”的二进制文件。C语言中的每条可执行语句经过编译后最终都将被…

Go语言中的HTTP请求发送

在Go语言中,发送HTTP请求是一种常见的网络操作。Go语言的net/http包提供了强大的API,使开发者能够轻松地构建HTTP请求并处理响应。 下面我们将详细介绍如何使用Go语言发送HTTP请求,包括设置请求参数、处理响应状态码和头部信息、发送JSON数据…

中湖盐——健康盐,盐中贵族

祁连山古老的盐湖,有一个水晶女和玉莹郎的传说,他们来到凡间做盐为生,做出的盐像水晶玉莹一样纯净。直到有一天,始皇帝传旨修长城,玉莹和水晶不忍百姓疾苦,用相思之泪化为了水晶般的白盐;血肉精华冶炼成萤石般的盐根,造福一方。 雪水溶积汇入的盐湖,水天倒映,美不胜收,中湖盐坚…

Zero-Shot Learning—A Comprehensive Evaluation of the Good, the Bad and the Ugly

目录 背景知识why zero-shot learning?广义零样本学习设置 1 INTRODUCTION1.1 zero-shot learning——methods1.2 zero-shot learning——datasets1.3 zero-shot learning——evaluation protocol 2 RELATED WORK2.1 早期工作2.1.1 Attribute-based classification for zero-s…

STC8H8K蓝牙智能巡线小车——3.按键开关状态获取

电路分析 引脚为P37开关未按下时,P37是高电平开关按下时,GND导通,P37是低电平 编程思路 Driver目录中添加KEY.h文件,应包含引脚定义、开关GPIO实例化函数、开关状态获取函数以及当按下和未按下时执行不同的函数(函数…

多级缓存架构(三)OpenResty Lua缓存

文章目录 一、nginx服务二、OpenResty服务1. 服务块定义2. 配置修改3. Lua程序编写4. 总结 三、运行四、测试五、高可用集群1. openresty2. tomcat 通过本文章,可以完成多级缓存架构中的Lua缓存。 一、nginx服务 在docker/docker-compose.yml中添加nginx服务块。…

全光谱护眼灯有哪些?寒假护眼台灯推荐

全光谱指的是包含了整个可见光谱范围以及部分红外和紫外光的光线。通常的白炽灯或荧光灯只能发出有限范围内的光波,而全光谱台灯通过使用多种类型的LED灯或荧光灯管来产生更广泛的光谱。这样的光谱更接近自然光,能够提供更真实的颜色还原和更好的照明效果…

Spring Cloud微服务基础入门

文章目录 发现宝藏前言环境准备创建第一个微服务1. 创建Spring Boot项目2. 创建微服务模块3. 编写微服务代码4. 创建一个简单的REST控制器 运行微服务 总结好书推荐 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不…