Java 设计模式——外观模式

news2024/11/28 7:17:28

目录

  • 1.概述
  • 2.结构
  • 3.实现
    • 3.1.子系统类
    • 3.2.外观类
    • 3.3.测试
  • 4.优缺点
  • 5.使用场景
  • 6.源码解析

1.概述

(1)有些人可能炒过股票,但其实大部分人都不太懂,这种没有足够了解证券知识的情况下做股票是很容易亏钱的,刚开始炒股肯定都会想,如果有个懂行的帮帮手就好,其实基金就是个好帮手,支付宝里就有许多的基金,它将投资者分散的资金集中起来,交由专业的经理人进行管理,投资于股票、债券、外汇等领域,而基金投资的收益归持有者所有,管理机构收取一定比例的托管管理费用。

(2)外观模式 (Facade Pattern) 是一种结构型设计模式,又称为门面模式,它提供了一个统一的接口,用于简化复杂系统或子系统的接口,并将其封装成一个更高级别的接口。外观模式隐藏了系统的复杂性,通过定义一个高层接口,使得客户端与系统的交互更加简单和方便。此外,外观模式是迪米特法则的典型应用。

在这里插入图片描述

2.结构

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

  • 外观 (Facade) 角色:外观对象是客户端与子系统之间的中间层,它封装了一组相关的子系统接口,对客户端提供一个更简单、更高层次的接口。
  • 子系统 (Subsystem) 角色:子系统是完成真正业务逻辑的组件,它包含了一系列相互关联的类和方法。每个子系统都有自己的功能和职责,但客户端可能不需要直接与子系统进行交互。

3.实现

【例】智能家电控制:小明的爷爷已经 60 岁了,一个人在家生活:每次都需要打开灯、打开电视、打开空调;睡觉时关闭灯、关闭电视、关闭空调;操作起来都比较麻烦。所以小明给爷爷买了智能音箱,可以通过语音直接控制这些智能家电的开启和关闭。类图如下:
在这里插入图片描述
具体实现代码如下:

3.1.子系统类

Light.java

public class Light {
    public void on(){
        System.out.println("打开电灯......");
    }
    
    public void off(){
        System.out.println("关闭电灯......");
    }
}

TV.java

public class TV {
    public void on(){
        System.out.println("打开电视机......");
    }
    
    public void off(){
        System.out.println("关闭电视机......");
    }
}

AirCondition.java

public class AirCondition {
    public void on(){
        System.out.println("打开空调......");
    }
    
    public void off(){
        System.out.println("关闭空调......");
    }
}

3.2.外观类

SmartAppliancesFacade.java

//外观类,用户主要和该类对象进行交互
public class SmartAppliancesFacade {
    //聚合电灯对象、电视机对象、空调对象
    private Light light;
    private TV tv;
    private AirCondition airCondition;
    
    public SmartAppliancesFacade() {
        light = new Light();
        tv = new TV();
        airCondition = new AirCondition();
    }

    //通过语言控制
    public void say(String message) {
        if (message.contains("打开")) {
            on();
        } else if (message.contains("关闭")) {
            off();
        } else {
            System.out.println("我还听不懂你说的!!!");
        }
    }

    //一件打开功能
    public void on() {
        light.on();
        tv.on();
        airCondition.on();
    }

    //一件关闭功能
    public void off() {
        light.off();
        ;
        tv.off();
        airCondition.off();
    }
}

3.3.测试

Client.java

public class Client {
    public static void main(String[] args) {
        //创建智能音箱对象
        SmartAppliancesFacade facade = new SmartAppliancesFacade();
        //控制家电
        facade.on();
        System.out.println("==========");
        //关闭家电
        facade.off();
    }
}

输出结果如下:

打开电灯......
打开电视机......
打开空调......
==========
关闭电灯......
关闭电视机......
关闭空调......

4.优缺点

(1)外观模式有以下几个优点:

  • 简化客户端的调用:通过外观对象提供的简单接口,客户端可以更方便地与系统进行交互,不需要了解系统的复杂性和内部结构。
  • 将客户端与子系统解耦:外观模式将子系统封装起来,客户端只需要与外观对象进行交互,而不需要与各个子系统直接交互,降低了客户端与子系统之间的耦合度。
  • 提高代码的可维护性:通过将复杂的系统逻辑封装在外观对象中,提升了代码的可读性和可维护性。修改系统时,只需调整外观对象的接口,而不需要修改客户端代码。
  • 提供统一的接口:外观对象为系统的各个子系统定义了一个统一的接口,使得系统更易于理解和使用。

(2)外观模式也有一些缺点:

  • 过度增加了一个新的抽象层:外观模式引入了一个新的外观对象,可能会导致系统中类的数量增加,从而增加了系统的复杂性。
  • 不符合开闭原则:当系统的功能发生变化时,可能需要修改外观对象的接口,这可能会影响到客户端代码。
  • 不能完全隐藏子系统的复杂性:外观模式可以隐藏一部分子系统的复杂性,但如果客户端需要直接访问子系统的一些细节,就无法避免与子系统发生直接交互。

5.使用场景

(1)外观模式适用于以下情况:

  • 当需要简化复杂系统或子系统的接口时,可以使用外观模式。例如,一个系统包含多个子系统,每个子系统有自己的接口,但客户端可能不需要直接调用所有子系统的接口,此时可以使用外观模式将这些子系统接口封装成一个更高层级的接口。
  • 当需要将系统与客户端分离并提高系统可维护性时,可以使用外观模式。通过将系统的复杂性封装到外观对象中,可以减少客户端代码与子系统之间的耦合,并提高代码的可读性和可维护性。
  • 当需要对现有系统进行重构时,可以使用外观模式。通过增加外观对象,可以将系统的接口分层并提高代码的结构性,从而使系统更加易维护。

(2)总之,外观模式适用于需要简化系统接口、分离客户端与子系统之间的耦合度、提高代码可维护性以及改善系统的可用性和可理解性的情况。它是一个常用的结构型设计模式,在实际开发中有着广泛的应用。

6.源码解析

(1)使用 Tomcat 作为 web 容器时,接收浏览器发送过来的请求,Tomcat 会将请求信息封装成 ServletRequest 对象,如下图 ① 处对象。但是仔细想想 ServletRequest 是一个接口,它还有一个子接口 HttpServletRequest,而我们知道该 request 对象肯定是一个 HttpServletRequest 对象的子实现类对象,到底是哪个类的对象呢?可以通过输出 request 对象,我们就会发现是一个名为 RequestFacade 的类的对象。

在这里插入图片描述
(2)RequestFacade 类就使用了外观模式。其结构图如下所示:
在这里插入图片描述

(3)为什么在此处使用外观模式呢?
定义 RequestFacade 类,分别实现 ServletRequest ,同时定义私有成员变量 Request ,并且方法的实现调用 Request 的实现。然后,将 RequestFacade上转为 ServletRequest 传给 servlet 的 service 方法,这样即使在 servlet 中被下转为 RequestFacade ,也不能访问私有成员变量对象中的方法。既用了 Request ,又能防止其中方法被不合理的访问。

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

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

相关文章

2023测试开发常见面试题

1. 什么是软件测试, 谈谈你对软件测试的了解 软件测试就是验证产品特性是否符合用户需求, 软件测试贯穿于软件的整个生命周期. >>> 那软件测试具体是什么呢 ? 就拿生活中的例子来说, 比如说我们去商场买衣服, 会有以下几个步骤: 第一步:…

leetcode:189. 轮转数组(python3解法)

难度:中等 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4]解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3…

Spring @Value注解读取yml配置文件中的list和map

配置文件 myConfig:userList: 张三,李四userMap: {"张三":"10","李四":"20"} 读取代码 Value("${myConfig.userList}")private List<String> userList;Value("#{${myConfig.userMap}}")private Map<S…

数据结构线性表——单链表

前言&#xff1a;小伙伴们又见面啦&#xff0c;这篇文章我们来一起学习线性表的第二模块——单链表。 单链表的学习就要开始上强度啦&#xff0c;小伙伴们一定要努力&#xff0c;坚持&#xff01; 目录 一.什么是单链表 二.单链表与顺序表的区别 三.单链表的实现 1.单链表…

如何使用Node.js快速创建HTTP服务器并实现公网访问本地Server

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 前言 Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation&#xff0…

11月起,33个省份纳入数电票开票试点范围内,发票无纸化已是大势所趋!

10月底&#xff0c;北京、贵州、山东&#xff08;不含青岛市&#xff09;、湖南、宁夏5个地区相继发布开展数电票试点工作的通知&#xff0c;至此&#xff0c;全国已有33个省份纳入数电票开票试点范围内。根据上述5地区发布的相关公告&#xff0c;11月1日将正式推行“数电票”开…

Java-认识类和对象

本章重点&#xff1a; 1. 掌握类的定义方式以及对象的实例化 2. 掌握类中的成员变量和成员方法的使用 3. 掌握对象的整个初始化过程 4. 掌握封装特性 5. 掌握代码块 6. 掌握内部类 1. 面向对象的初步认知 1.1 什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Pro…

HarmonyOS ArkTS基础知识

概述 上一节&#xff0c;学习了TypeScript的基础语法&#xff0c;而在鸿蒙开发当中&#xff0c;有基于自己的编程语言&#xff0c;便是ArkTS。它是一种声明式UI的编程范式的语言&#xff0c;开发框架如下图所示&#xff1a; 根据框架图&#xff0c;分析&#xff0c;我将它大致…

2023_11_6 每日半小时 SQL 刷题

文章目录 1. 查询所有列题目描述SQL 语句编写 2. 查询多列题目描述SQL 语句编写 3. 查询结果去重题目描述SQL 语句编写 4. 查询结果限制返回行数题目描述SQL 语句编写 5. 将查询后的列重新命名题目描述SQL 语句编写 语法小总结 1. 查询所有列 题目链接&#xff1a;SQL1 查询所…

SAP-MM-批量扩充视图

MM50 可以通过这个程序批量维护或查看这个物料没有维护的视图&#xff0c;进行扩充。

weblogic弱口令漏洞复现

文章目录 一、漏洞特征1.可以直接获取passwd文件2.可以直接获取密文文件3.可以直接获取密钥文件4.解密密码5.登录后台 二、命令执行复现1.部署webshell2.Shell命令执行3.jsp一句话木马 一、漏洞特征 1.可以直接获取passwd文件 http://192.168.232.131:7001/hello/file.jsp?p…

找茬小游戏源码系统 无聊就来玩一玩 带完整的搭建教程

找茬小游戏是一种经典的休闲游戏&#xff0c;它以找出不同之处为核心玩法&#xff0c;锻炼玩家的观察力和反应能力。随着互联网技术的发展和普及&#xff0c;越来越多的游戏开发者开始尝试开发这种简单有趣的游戏。下面源码小编就来给大家介绍一下这款源码系统的搭建教程以及核…

哈夫曼编码与解码,基于Python实现

from itertools import count from collections import Counter from heapq import heapify, heappush, heappopdef huffman_tree(s):# 统计每个字符出现的次数s Counter(s) # 计算可迭代序列中元素的数量&#xff0c;返回字典类型数据c…

2023年09月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 有一组数据存在列表中,things[“桌子”,“椅子”,“茶几”,“沙发”,“西瓜”,“苹果”,“草莓”,“香蕉”]&#xff0…

Python如何实现查看WiFi密码?

由于最近公司加强对无线安全的管理&#xff0c;wifi密码从以前的12345678&#xff0c;变成复杂难记的一串&#xff0c;导致我时常忘记WIFI密码&#xff0c;而遭受同事的“毒打”。由于我不是那种喜欢打扰同事认真工作的人&#xff0c;于是&#xff0c;我决定用python来试试&…

【Spring】注解

文章目录 1. 前言2.注解开发的准备工作3. IOC相关注解DI相关注解 4. DI相关注解4.1 Value4.2 AutoWired4.3 Qualifier 5. xml配置文件相关注解5.1 Configuration5.2 ComponensScan 6.Bean注解7. PropertySource 1. 前言 Spring支持使用注解代替xml配置,注解开发可以简化配置. …

如何备战秋季招聘:从规划到面试的全方位攻略

如何备战秋季招聘&#xff1a;从规划到面试的全方位攻略 随着秋天的到来&#xff0c;秋季招聘也进入了高峰期。对于即将毕业的同学们来说&#xff0c;抓住这个黄金时期&#xff0c;找到一份满意的工作至关重要。本文将为你提供一份全面的秋季招聘攻略&#xff0c;从规划到面试&…

<微信小程序>《微信小程序开发笔记》(二)

《微信小程序开发笔记》&#xff08;二&#xff09; 1 程序开发1.1 原则&#xff08;自己感悟&#xff09;1.2 架构1.3 开发模式 2 建立项目3 微信代码构成3.1 JSON 配置文件3.2 WXML 模板文件3.3 WXSS 样式文件3.4 JS 脚本逻辑文件 1 程序开发 1.1 原则&#xff08;自己感悟&…

吴翰清《计算》重磅来袭,为了可计算的价值,写给所有人!

《计算》终于出版了 计算&#xff0c;为了可计算的价值 撰文 | 吴翰清 三年前在新冠疫情大爆发期间&#xff0c;当我决心动笔写下第一行文字时&#xff0c;从来没想到过写作《计算》的工程会如此之大。 它横跨了人类文明三千年的数学史和计算机科学史&#xff0c;从数字的起…

【JMeter】定时器分类以及场景介绍

1. 定时器分类 固定定时器 作用&#xff1a;请求之间设置等待时间应用场景&#xff1a;查询商品列表后&#xff0c;去查看列表商品详情页。针对商品列表数据量比较大的&#xff0c;响应时间会比较长&#xff0c;就需要设置等待时间然后去查看商详 2.定时器的作用域&#xff1…