【再探】设计模式—适配器、装饰及外观模式

 结构型设计模式是用于设计对象和类之间关系的一组设计模式。一共有7种:适配器模式、装饰器模式、外观模式、桥接模式、组合模式、享元模式及代理模式。

1 适配器模式

需求:在软件维护阶段,已存在的方法与目标接口不匹配,需要个中间类来适配这个方法。

1.1 适配器模式介绍

将一个类的接口转换成客户端期望的目标类格式,使得原本不兼容的类可以一起工作。

图 适配器模式 UML

public class AdapterPattern {public static void main(String[] args) {SimpleEncrypt simpleEncrypt = new SimpleEncrypt();EncryptAdapter adapter = new EncryptAdapter(simpleEncrypt);String encrypt = adapter.encrypt("hello adapter");System.out.println(encrypt);}private interface Encrypt {String encrypt(String text);}private static class EncryptAdapter implements Encrypt{private static final int ENCRYPT_LENGTH = 15;private final SimpleEncrypt simpleEncrypt;private EncryptAdapter(SimpleEncrypt simpleEncrypt) {this.simpleEncrypt = simpleEncrypt;}@Overridepublic String encrypt(String text) {return simpleEncrypt.encrypt(text,ENCRYPT_LENGTH);}}private static class SimpleEncrypt {public String encrypt(String text,int length) {return text + length;}}}

对象适配器

在适配类中关联一共被适配者对象,通过调用被适配者对象的方法来实现适配。

类适配器

实现目标接口的同时,继承被适配者类。

接口适配器

通过一个抽象类来实现接口中的所有方法。具体类通过继承抽象类,根据需求只需要重写特定的方法。

表 适配器种类

1.2 优缺点

优点:

  1. 提高代码的复用性,让原本不兼容的类可以协同工作。
  2. 降低系统耦合度,客户端只与适配器进行交互。

缺点:

  1. 过度使用适配器可能导致系统变得复杂,难以理解和维护,也可能导致性能下降。

2 装饰模式

需求:1)想给给类添加新的功能。而不希望使用继承的方式。2)动态添加及撤销功能。

2.1 装饰模式介绍

在不改变一个对象的接口的前提下,通过创建一个装饰者来包裹真实对象,来动态地增加额外的职责到该对象

图 装饰模式 UML

完全透明

装饰对象和原始对象具有相同的接口,客户端不需要区分装饰对象及原始对象。

半透明

允许装饰对象的接口与原始对象的接口不完全一致。装饰对象的接口可能会比原始对象更宽,但仍需要实现原始对象的接口。

表 装饰模式的两种模式

public class DecoratorPattern {public static void main(String[] args) {String text = "hello decorator";Verifier noEmptyVerifier = new NoEmptyVerifier();Verifier minLengthVerifier = new MinLengthVerifier(noEmptyVerifier,7);System.out.println(minLengthVerifier.verification(text));}private interface Verifier {boolean verification(String text);}private static class NoEmptyVerifier implements Verifier {@Overridepublic boolean verification(String text) {return text != null && text.trim().length() > 0;}}private static class MinLengthVerifier implements Verifier {private final int DEFAULT_MIN_LENGTH = 15;private final Verifier verifier;private int minLength = DEFAULT_MIN_LENGTH;private MinLengthVerifier(Verifier verifier) {this.verifier = verifier;}public MinLengthVerifier(Verifier verifier, int minLength) {this.verifier = verifier;this.minLength = minLength;}@Overridepublic boolean verification(String text) {return verifier.verification(text) && text.length() > minLength;}}}

2.2 优缺点

优点:

  1. 提供了比继承更多的灵活性。
  2. 可以创建一个功能更加强大的对象,通过对一个对象进行多次装饰。
  3. 可以动态的添加及撤销功能。

缺点:

  1. 会产生很多小对象,如果过度使用,可能会导致程序变得复杂且难以维护。
  2. 在某些情况下,调试和排查问题的难度增加。

3 外观模式

需求:与系统交互时,不想与系统的其他业务模块产生关联,希望与一个统一的角色进行交互。

3.1 外观模式介绍

客户端与系统的通信通过一个统一的外观角色进行。

图 外观模式 UML

public class FacadePattern {public static void main(String[] args) { // 客户端SystemController controller = SystemController.getInstance();System.out.println(controller.getUser("facade"));}private static class SystemController { // 对外的接口private static volatile SystemController instance;public static SystemController getInstance() {if (instance == null) {synchronized (SystemController.class) {if (instance == null) {UserService service = new UserService(new UserMapper());instance = new SystemController(service);}}}return instance;}private final UserService userService;private SystemController(UserService userService) {this.userService = userService;}public String getUser(String username) {return userService.getUser(username);}}private static class UserService {private final UserMapper userMapper;private UserService(UserMapper userMapper) {this.userMapper = userMapper;}public String getUser(String username) {if (username == null) return "";return userMapper.searcherByUsername(username);}}private static class UserMapper {public String searcherByUsername(String username) {return "用户+" + username;}}}

3.2 优缺点

优点:

1)将客户端与系统内部模块分隔开,符合迪米特法则,降低了耦合度。

缺点:

1)不符合开闭原则。

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

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

相关文章

论文阅读:RHO-1:Not All Tokens Are What You Need 选择你需要的 Tokens 参与训练

论文链接:https://arxiv.org/abs/2404.07965 以往的语言模型预训练方法对所有训练 token 统一采用 next-token 预测损失。作者认为“并非语料库中的所有 token 对语言模型训练都同样重要”,这是对这一规范的挑战。作者的初步分析深入研究了语言模型的 t…

记录一个练手的js逆向password

很明显 请求加密了password 全局搜索 有个加密函数(搜不到的可以搜临近的其他的关键字 或者url参数) 搜索的时候一定要仔细分析 我就没有仔细分析 我搞了好久 又是xhr又是hook的(还没hook到) 我当时也是疏忽了 我寻思这个也不是js文件 直到后来 我怎么也找不到 我就猜想 不…

代码随想录算法训练营DAY44|C++动态规划Part6|完全背包理论基础、518.零钱兑换II、377. 组合总和 Ⅳ

文章目录 完全背包理论基础完全背包问题的定义与01背包的核心区别为什么完全背包的循环顺序可以互换?CPP代码 ⭐️518.零钱兑换II思路CPP代码 ⭐️377. 组合总和 Ⅳ思路CPP代码 扩展题 完全背包理论基础 卡码网第52题 文章链接:完全背包理论基础 视频链接…

【数据结构与算法】力扣 102. 二叉树的层序遍历

题目描述 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入: root [3,9,20,null,null,15,7] 输出: [[3],[9,20],[15,7]]示例 2&#x…

上证50etf期权到底该怎么玩?

今天期权懂带你了解上证50etf期权到底该怎么玩?ETF期权是一种股票市场上的金融衍生品,它是在交易所上市交易的期权合约,其标的资产是某个特定的交易所交易基金(ETF),如上证50指数ETF或沪深300指数ETF等。 上…

Git命令Gitee注册idea操作git超详细

文章目录 概述相关概念下载和安装常见命令远程仓库介绍与码云注册创建介绍码云注册远程仓库操作关联拉取推送克隆 在idea中使用git集成add和commit差异化比较&查看提交记录版本回退及撤销与远程仓库关联 push从远程仓库上拉取,克隆项目到本地创建分支切换分支将…

(✌)粤嵌—2024/5/7—除自身以外数组的乘积

代码实现&#xff1a; /*** Note: The returned array must be malloced, assume caller calls free().*/ int* productExceptSelf(int *nums, int numsSize, int *returnSize) {// 左乘积int l[numsSize];l[0] 1;for (int i 1; i < numsSize; i) {l[i] l[i - 1] * nums[…

Cesium学习——渲染、加载GeoJSON、调整位置

渲染概述 作者&#xff1a;当时明月在曾照彩云归 出处&#xff1a;https://www.cnblogs.com/jiujiubashiyi/p/17124717.html 1. 引言 Cesium是一款三维地球和地图可视化开源JavaScript库&#xff0c;使用WebGL来进行硬件加速图形&#xff0c;使用时不需要任何插件支持&#xf…

以中国为目标的DinodasRAT Linux后门攻击场景复现

概述 在上一篇《以中国为目标的DinodasRAT Linux后门剖析及通信解密尝试》文章中&#xff0c;笔者对DinodasRAT Linux后门的功能及通信数据包进行了简单剖析&#xff0c;实现了对DinodasRAT Linux后门心跳数据包的解密尝试。 虽然目前可对DinodasRAT Linux后门的通信数据包进…

SecretFlow学习指南(3)框架拆解和使用

“隐语”架构设计全貌 1.隐语框架设计思想 隐私计算是一个新兴的跨学科领域&#xff0c;涉及密码学、机器学习、数据库、硬件等多个领域。根据过去几年的实践经验&#xff0c;我们发现 ●隐私计算技术方向多样&#xff0c;不同场景下有其各自更为合适的技术解决方案 ●隐私计算…

Windows系统安装MySQL数据库详细教程

【确认本地是否安装mysql】 &#xff08;1&#xff09;按【winr】快捷键打开运行&#xff1b; &#xff08;2&#xff09;输入services.msc&#xff0c;点击【确定】&#xff1b; &#xff08;3&#xff09;在打开的服务列表中查找mysql服务&#xff0c;如果没有mysql服务&am…

麦肯锡精英高效阅读法笔记

系列文章目录 如何有效阅读一本书笔记 读懂一本书笔记 麦肯锡精英高效阅读法笔记 文章目录 系列文章目录序章 无法读书的5个理由无法读书的理由① 忙于工作&#xff0c;没时间读书无法读书的理由② 不知应该读什么无法读书的理由③ 没读完的书不断增多无法读书的理由④ 工作繁…

《QT实用小工具·五十三》会跑走的按钮

1、概述 源码放在文章末尾 该项目实现了会逃跑的按钮&#xff1a; 两个按钮&#xff0c;一个为普通按钮&#xff0c;另一个为会跑走的按钮 鼠标移到上面时&#xff0c;立刻跑掉 针对鼠标、键盘、触屏进行优化 随机交换两个按钮的文字、偶尔钻到另一个按钮下面、鼠标移开自…

2024.1.1 IntelliJ IDEA 使用记录

2024.1.1 IntelliJ IDEA 使用记录 下载设置文件编码maven 配置 插件可以中文语言包安装lombok 插件Smart Tomcat ( 根据需要安装)Smart Tomcat 配置 项目导入java 设置maven 配置 项目运行SpringBoot 项目运行tomcat 运行 (根据需要)相关依赖添加运行配置 下载 IntelliJ IDEA …

0基础学PHP有多难?

php作为web端最佳的开发语言&#xff0c;没有华而不实&#xff0c;而是经受住了时间考验&#xff0c;是一门非常值得学习的编程语言。 目前市场上各种网站、管理系统、小程序、APP等&#xff0c;基本都是使用PHP开发的&#xff0c;也侧面反映了PHP的需求以及学习的必要性&…

前端传递list(数组)类型参数,后端接收失败

一顿报错,我之前遇到的list都是Long类型 貌似用GET也是可以的,但是很奇怪一直报错 就是不可以 后来去百度 查询到可以用两种方法解决这个问题 1、拆开 传 以GET方式&#xff0c;后端GetMappingRequestParam接收。 2、以Post方式传&#xff0c;后端创建dto PostMappingReques…

55. 【Android教程】位图:Bitmap

在上一节学习 Drawable 图像资源的时候我们在很多地方用到了 bitmap&#xff0c;bitmap 其实就是真实图片在 Android 中最直接的表现形式&#xff0c;这一节我们来仔细学习一下 Bitmap 的使用。 1. 什么是 Bitmap Bitmap 在 Android 中对应一张图片文件&#xff0c;它是一个二…

普通人可以做什么兼职副业?推荐7 种卖情怀的生意,小众高利润

一瓶茅台&#xff0c;尽管成本仅为70元&#xff0c;但其建议零售价却高达1499元&#xff0c;而在市场上的流通价格更是突破了2600元大关。同样的一款手提包&#xff0c;在网络上仅售几百元&#xff0c;但一旦贴上了LV的标志&#xff0c;其售价便瞬间飙升至一万多元。这究竟是为…

【超好用的前端表单辅助功能】

前端表单辅助功能 1. 根据模块自动生成目录锚点定位2. 描点定位动态组件3. 隔离组件&#xff0c;组件内部实现校验逻辑&#xff0c;交给提交按钮统一处理4. 选择不同的类型需要重组不同的模块展示&#xff0c;并整合数据传给后端 最近做了一个复杂的表单&#xff0c;涉及到的技…

AI实景自动无人直播软件:引领直播行业智能化革命;提升直播效果,无人直播软件助力智能讲解

随着科技的快速发展&#xff0c;AI实景自动无人直播软件正在引领直播行业迈向智能化革命。它通过智能讲解、一键开播和智能回复等功能&#xff0c;为商家提供了更高效、便捷的直播体验。此外&#xff0c;软件还支持手机拍摄真实场景或搭建虚拟场景&#xff0c;使直播画面更好看…