Java设计模式之结构型-外观模式(UML类图+案例分析)

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

五、总结


一、基础概念

外观模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

二、UML类图

三、角色设计

角色描述
外观(Facade)角色提供了一个统一的接口,用来访问子系统中的一群接口。例如购物这个外观角色。
子系统(Sub System)角色实现系统的部分功能,客户可以通过外观角色访问它。例如:购买步骤、支付方式。

四、案例分析

外观模式就像一个遥控器,它把许多电器的开关集中到了一个遥控器上,你只需要按遥控器上简单的按钮就可以控制电视、空调等电器开关。

1、电视、空调等电器就是不同的子系统。

2、遥控器是外观类,它将电视、空调的开关简单封装起来,提供了简单的接口(按钮)。

3、用户(客户端)只需要按遥控器的按钮,而不需要去操作每一个电器的开关。

4、如果需要替换一个新的电视,只要修改遥控器上的电视按钮对应代码,对客户端无影响。这样通过遥控器(外观类)把复杂的子系统简化和封装起来,用户就只需要操作简单的接口,大大降低了系统的复杂性。同时在修改子系统时,也只会影响外观类而不会影响到客户端。

总之,外观模式提供了一个简单入口来访问和使用复杂子系统,它对客户屏蔽了子系统组件,减少系统相互依赖,实现解耦。

假设现在有一个简单的例子:平日我们网上购物一般会分为4个步骤,挑选物品,添加购物车,填写收获信息和支付,下面我们就通过代码来实现上述功能。

定义一个网上购物的流程接口:

public interface PurchaseProcess {

    //挑选物品
    void pickGoods(String goodName);

    //添加到购物车
    void addCart(String goodName);

    //填写收货信息
    void addConsigneeInformation(String consigneeInformation);

    //支付
    void pay();


}

购物接口对应的实现类:

public class PurchaseProcessImpl implements PurchaseProcess {
    @Override
    public void pickGoods(String goodName) {
        System.out.println("挑选的商品:"+goodName);
    }

    @Override
    public void addCart(String goodName) {
        System.out.println("将《"+goodName+"》添加到购物车!");
    }

    @Override
    public void addConsigneeInformation(String consigneeInformation) {
        System.out.println("您填写的收货地址:"+consigneeInformation);
    }

    @Override
    public void pay() {
        System.out.println("支付完成...");
    }
}

提供一个统一的方法进行购物:

public class Shopping {

    private PurchaseProcessImpl purchaseProcess = new PurchaseProcessImpl();

    public void purchaseGoods(String goodName,String consigneeInformation) {
        purchaseProcess.pickGoods(goodName);
        purchaseProcess.addCart(goodName);
        purchaseProcess.addConsigneeInformation(consigneeInformation);
        purchaseProcess.pay();
    }
}

主方法测试:

public class Client{
    public static void main(String[] args) {
        Shopping shopping = new Shopping();
        shopping.purchaseGoods("华为Mate40 Pro","上海");
    }
}

运行结果:

如果需要添加支付方式呢,我们还需要重新设计购买的步骤,具体的代码实现如下:

定义一个支付方式实现类: 

public class PayMode {
    public void payMode(String payMode){
        System.out.println("支付方式:"+payMode);
    }
}

改造购物方式方法中的代码,新增一个支付方式:

public class Shopping {

    private PurchaseProcessImpl purchaseProcess = new PurchaseProcessImpl();

    private PayMode mode = new PayMode();

    public void purchaseGoods(String goodName,String consigneeInformation,String payMode) {
        purchaseProcess.pickGoods(goodName);
        purchaseProcess.addCart(goodName);
        purchaseProcess.addConsigneeInformation(consigneeInformation);
        mode.payMode(payMode);
        purchaseProcess.pay();
    }
}

主方法测试:

public class Client{
    public static void main(String[] args) {
        Shopping shopping = new Shopping();
        shopping.purchaseGoods("华为Mate40 Pro","上海","支付宝");
    }
}

运行结果:

五、总结

优点:

1、减少系统相互依赖:外观模式使得客户端和子系统的复杂关系放在外观类中,外界仅需面对一个简单的外观类,大大降低了客户与子系统间的耦合关系。

2、提高灵活性:通过引入外观类,可以在不影响其他子系统的情况下修改子系统。

3、更好的层次结构:外观模式可以更好地定义系统不同层次的功能

缺点:

1、不符合开闭原则。如果需要修改外观类,有可能需要修改所有客户端代码。

使用场景:

1、提供一个简单的接口以屏蔽子系统组件的复杂性。

2、在层次化结构中定义入口点。

符合的设计原则:

1 依赖倒转原则(Dependence Inversion Principle)

外观类与子系统之间形成了一种逆向的依赖关系,外观类依赖于抽象接口,而子系统则实现这些抽象接口,这个依赖关系是倒置的,降低了外观类与子系统的耦合度。

2 迪米特法则(Law of Demeter)

外观类与子系统之间遵循最小知识原则,外观类只与需要交互的子系统直接通信,而不关心子系统内部的实现细节,降低了耦合度。

简单来说,外观模式通过提供一个高层接口来封装细节,简化子系统使用,使子系统之间解耦,它提高了程序的灵活性和可维护性。 

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

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

相关文章

初识Spring - 什么是IoC容器?

目录 一、Spring是什么? Spring就是包含了很多工具方法的 IoC 容器。 1. 什么是IoC,什么是容器 2. IoC的优点 (解决耦合问题) 二、什么是Spring IoC 1. Spring IoC详解 (1)也就是学习 Spring 最核心的功能: &…

Redis主从哨兵模式

IP 服务 用途 10.0.10.45 redis sentinel zookeeper uniquecode 主redis 10.0.10.43 redis sentinel zookeeper uniquecode 从reids-1 10.0.10.44 redis sentinel zookeeper uniquecode 从redis-2 redis主从哨兵分为两部分,redis主从和redis哨兵 redi…

【分布式】 ELK 企业级日志分析系统 二

目录 一、FilebeatELK 部署1.1 环境部署 二、grok 正则捕获插件mutate 数据修改插件multiline 多行合并插件date 时间处理插件 一、FilebeatELK 部署 1.1 环境部署 Node1节点(2C/4G):node1/192.168.137.101 Elasticsearch Node2节点&…

反常积分定义

目录 反常积分的定义 判断敛散性的方法 方法2: 例题 无界函数的反常积分 判断敛散性的方法 例题 反常积分的定义 该极限存在就表示该反常积分收敛 对于定义3,只有两个都收敛的情况下,原反常积分才收敛。 判断敛散性的方法 始终大的函数形成…

ACWing算法基础课

y总说 java不能用Scanner读入,要用Buffer.read();快十倍二十倍; y总19年5月的视频,牛13! 第一讲 基础算法 包括排序、二分、高精度、前缀和与差分、双指针算法、位运算、离散化、区间合并等内容。 快速排序 一定要先移动end(就是把大数移到右边),后移动start; 否则 先找…

【云原生|Docker系列第2篇】Docker的安装和配置

欢迎来到Docker入门系列的第二篇博客!在上一篇博客中,我们已经介绍了Docker的基本概念和作用,以及为什么它成为现代应用开发和部署的关键技术。本篇博客将着重讨论Docker的安装和配置,帮助您开始使用Docker并为您的应用程序提供一…

第十章——对象和类

面向对象编程(OOP)是一种特殊的、设计程序的概念性方法,下面是最重要的OOP特性: 抽象封装和数据隐藏多态继承代码的可重用性 为了实现这些特性并将它们组合在一起,C所做的最重要的是提供了类 采用过程性编程首先考虑…

OpenCV 入门教程:像素访问和修改

OpenCV 入门教程:像素访问和修改 导语一、像素访问1.1 获取图像的大小1.2 访问图像的像素值1.3 修改图像的像素值 二、示例应用2.1 图像反转2.2 阈值化操作 三、总结 导语 在图像处理和计算机视觉领域,像素级操作是非常重要和常见的任务之一。通过像素访…

Oracle的CentOS安装

1.CentOS环境 阿里云轻量型服务器 2核-4g内存-80G系统盘 2.Oracle下载 Oracle下载 Oracle 数据库免费 CPU 限制 Oracle 数据库免费版自动将自身限制为两个内核进行处理。例如,在具有 2 个双核 CPU(四个核)的计算机上,如果大量…

mac批量在文件名前面加相同文字?

mac批量在文件名前面加相同文字?你平时在使用电脑进行工作或者学习的时候,是不是需要做一些关于文件整理和保存的操作呢,并且还需要对一大堆的文件进行重名呢?相信很大多数小伙伴都要面对这些,经常需要将大量文件的名称…

SpringBoot学习——追根溯源servlet是啥,tomcat是啥,maven是啥 springBoot项目初步,maven构建,打包 测试

目录 引出追根溯源,过渡衔接servlet是啥?tomcat是啥? 前后端开发的模式1.开发模式:JavaWeb:MVC模型2.Web:Vue,MVVC模型3.后端相关3.1 同步与异步3.2 Controller层3.3 Service层:要加…

阐述kubernetes部署:基础设施安装

基础设施部署 持久卷的建立 请参考:《持久卷的建立》 elasticsearch部署 一、设置远程扩展字典 不使用自定义字典请忽略此步骤 首先更改ES中IK插件的配置: vi/opt/kubernetes/es/IKAnalyzer.cfg.xml 按您的实际设置的秘钥配置secret_value: …

华为配置LLDP基本功能

华为配置LLDP基本功能 1.什么是lldp协议 定义 LLDP(Link Layer Discovery Protocol)是IEEE 802.1ab中定义的链路层发现协议。LLDP是一种标准的二层发现方式,可以将本端设备的管理地址、设备标识、接口标识等信息组织起来,并发布给自己的邻居设备,邻居设备收到这些信息后将…

git提交只单个或者某几个文件的指令

git status --查看目前本地和远程仓库的差异; git add --提交某的文件,多次执行可以提交多个文件 文件名称替换 git stash -u -k --其他文件保留到本地暂存区,不进行提交 git commit -m ---针对本次修改添加注释并提交到远程仓库 gi…

在安卓手机搭建kali环境,手机变成便携式渗透神器

简介 kali是著名的黑客专用系统,一般都是直接装在物理机或者虚拟机上,我们可以尝试把kali安装在手机上,把手机打造成一个便携式渗透神器。 我们需要下载以下3款软件: (1).Termux(终端模拟器) (2).AnLinux(里边有各种安装liunx…

从零实现深度学习框架——带Attentiond的Seq2seq机器翻译

引言 本着“凡我不能创造的,我就不能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。 要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量不使用外部完备的框架前提下,实现我…

学校公寓管理系统/基于微信小程序的学校公寓管理系统

摘 要 社会的发展和科学技术的进步,互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个学生的使用。手机具有便利性,速度快,效率高,成本低等优点。 因此,构建符合自己要求的操作…

ChatGPT训练流程

图源:State of GPT - Microsoft Build 笔者翻译上图如下: 阶段子阶段目标备注Pre-Training--------语言建模Instruction Finetuning---------让模型能够理解自然语言指令RLHFReward Modeling奖励建模,用来代替人工打分,降低标注…

5G理论概述

文章目录 SA组网架构及协议栈4-5G核心网侧融合交互5G网络网元和设备类型,接口1、AMF(Access and Mobility Management Function),接入和移动管理功能2、SMF(Session Management function),会话管理功能3、AUSF&#xf…

2023数学建模国赛常用算法-Topsis优劣解距离法

更多国赛数学建模资料思路,关注文末! 1 优劣解距离法(TOPSIS)简介 1.1 概念 TOPSIS 法是一种常用的组内综合评价方法,能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。基本过程为基于…