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

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

五、总结


一、基础概念

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

二、UML类图

三、角色设计

角色描述
外观角色为多个子系统对外提供一个统一的接口,外观模式的核心,客户端可以调用这个接口实现对各个子系统的访问
子系统角色实现系统的部分功能,客户可以通过外观角色访问它们,子系统对外界隐藏了内部的复杂性
客户端角色通过一个外观角色访问各个子系统的功能,客户可以根据需要直接访问子系统类

四、案例分析

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

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 {@Overridepublic void pickGoods(String goodName) {System.out.println("挑选的商品:"+goodName);}@Overridepublic void addCart(String goodName) {System.out.println("将《"+goodName+"》添加到购物车!");}@Overridepublic void addConsigneeInformation(String consigneeInformation) {System.out.println("您填写的收货地址:"+consigneeInformation);}@Overridepublic 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)

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Modbus协议是什么?Modbus协议类型解析

什么是Modbus协议?Modbus 是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的一种工业控制总线协议,是全球第一个真正用于工业现场的总线协议。Modbus 以其简单、健壮、开放而且不需要特许授权的特点,成为通用通信协议。为了适应以太网环境&a…

RDS-Tools RDS-Knight Crack

RDS 高级安全性 利用全面的网络安全工具箱中有史以来最强大的安全功能集来保护您的 RDS 基础架构。 全方位 360 保护 无与伦比的功能集 无与伦比的物有所值 企业远程桌面安全。现代工作空间的智能解决方案。 办公室正在权力下放。远程办公室和移动员工数量创历史新高。随…

细节:双花括号({{ ... }})在Vue.js中的用法

问题&#xff1a; 为什么后端返回的是数字类型时&#xff0c; {{ form.orderPrice }}可以拿到值展示&#xff0c; {{ form.orderPrice || "-" }} 不可以&#xff1f; 接口返回数据&#xff1a; <el-form-item label"订单金额&#xff1a;" prop"…

Qt Creator常用快捷键及技巧

文章目录 1.[Qt Creator常用快捷键及技巧提升编码效率]2.win10上安装QT &#xff0c;选择安装组件3.qt配置过程中主要注意的几点4.目录结构附&#xff1a;网友整理快捷方式&#xff1a; 1.[Qt Creator常用快捷键及技巧提升编码效率] (https://blog.csdn.net/luoyayun361/artic…

ChatGPT 最佳实践指南之:使用外部工具

Use external tools 使用外部工具 Compensate for the weaknesses of GPTs by feeding them the outputs of other tools. For example, a text retrieval system can tell GPTs about relevant documents. A code execution engine can help GPTs do math and run code. If a …

graylog源码搭建

这里主要讲如何源码安装graylog 下载地址&#xff1a; https://www.graylog.org/downloads/ 下载带有JVM的源码文件源码安装 下载graylog-5.1.3-linux-x64.tgz&#xff0c;并上传到Centos中&#xff0c;执行以下操作 tar -zxvf graylog-5.1.3-linux-x64.tgzcd /etcmkdir -p …

ARPACK特征值求解分析

线性方程组求解、特征值求解是(数值)线性代数的主要研究内容。力学、电磁等许多问题&#xff0c;最终都可以归结为特征值、特征向量的求解。 ARPACK使用IRAM(Implicit Restarted Arnoldi Method)求解大规模系数矩阵的部分特征值与特征向量。了解或者熟悉IRAM算法&#xff0c;必…

Spring Boot中如何解决Redis的缓存穿透、缓存击穿、缓存雪崩?

Redis的缓存穿透、缓存击穿、缓存雪崩 一、概述 ① 缓存穿透&#xff1a;大量请求根本不存在的key ② 缓存雪崩&#xff1a;Redis中大量key集体过期 ③ 缓存击穿&#xff1a;Redis中一个热点key过期 三者出现的根本原因&#xff1a;Redis命中率下降&#xff0c;请求直接打…

机器学习 day27(反向传播)

导数 函数在某点的导数为该点处的斜率&#xff0c;用height / width表示&#xff0c;可以看作若当w增加ε&#xff0c;J(w,b)增加k倍的ε&#xff0c;则k为该点的导数 反向传播 tensorflow中的计算图&#xff0c;由有向边和节点组成。从左向右为正向传播&#xff0c;神经网…

常用的缓存工具有ehcache、memcache和redis,这里介绍spring中ehcache的配置。

常用的缓存工具有ehcache、memcache和redis&#xff0c;这里介绍spring中ehcache的配置。 1.在pom添加依赖&#xff1a; <!-- ehcache 相关依赖 --><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><ve…

ylb-接口13实名认证

总览&#xff1a; 在api模块下的service包&#xff0c;创建一个充值接口RechargeService&#xff0c;并创建一个&#xff08;根据userID查询它的充值记录&#xff09;方法&#xff1a; package com.bjpowernode.api.service;import com.bjpowernode.api.model.RechargeRecord…

【漂移-扩散通量重建 FV 方案】用于半导体和气体放电模拟的电子传输的更准确的 Sharfetter-Gummel 算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…