面向可复用性和可维护性的设计模式 课程学习总结
什么是设计模式
设计模式:在软件设计中给定上下文中常见问题的通用的、可重用的解决方案。
设计模式分类
1. 创建型模式——Creational patterns
关注对象创建的过程
1.1 工厂方法模式
定义用于创建对象的接口,但让子类决定要实例化哪个类。工厂方法允许类将实例化推迟到子类。
应用场景:当client不知道要创建哪个具体类的实例,或者不想在client代码中指明要具体创建的实例时,用工厂方法。
优点:无需将特定于应用程序的类绑定到代码中。代码仅处理接口,所以它可兼容其他子类。
缺点:增加代码量,需要额外增加一个Creator类及其子类。
2. 结构型模式——Structural patterns
处理类或对象的组合
2.1 适配器模式
将某个类/接口转换为client期望的其他形式
应用场景:需要在新系统中重用一个不兼容的老组件
如上图所示,为了实现Shape的display方法,对先前已存在的类—LegacyRectangle中的diaplay方法进行了重用
优点:实现了对已有类的大限度复用,避免“重新造轮子”。
缺点:适配器模式会引入额外的类和代码,这可能会增加系统的复杂性。此外,适配器模式有时会被用来掩盖设计上的问题,而不是解决它们。例如,适配器可能被用来连接不兼容的接口,但这可能是由于设计不良或缺乏整体架构考虑造成的。使用适配器模式可能会使得根本问题被忽视。
2.2 装饰器模式
实现子类特性的任意组合
应用场景:想要对子类实现多个特性的堆叠
上图为一个应用实例,通过逐层调用装饰器进行包装,实现特性的组合
优点:
- 动态扩展对象功能:装饰器模式允许在运行时动态地添加功能,而无需修改对象的类。这使得可以根据需要灵活地增加或移除功能。
- 遵循单一职责原则:每个装饰器类都专注于一个特定的功能扩展。这使得每个类的职责更加单一和明确,易于维护和理解。
- 替代继承:通过组合而不是继承来扩展对象的功能,避免了类爆炸(class explosion)问题。继承会导致大量的子类,而装饰器模式则通过不同装饰器的组合来实现相同的效果。
- 灵活性和可组合性:多个装饰器可以组合使用,以创建复杂的功能扩展。这种组合方式提供了极大的灵活性,允许以多种方式排列和组合装饰器。
- 透明性:客户端可以透明地使用装饰器,而无需知道对象被装饰了。装饰器模式对客户端是透明的,客户端代码无需修改即可使用增强功能的对象。
缺点:
- 增加代码复杂性:虽然装饰器模式提供了灵活性,但也增加了系统的复杂性。尤其是在装饰器链较长时,调试和排查问题可能变得困难。
- 较多的小类:由于每个具体装饰器都是一个独立的小类,这可能导致系统中类的数量增加,从而增加维护和管理的难度。
3. 行为类模式——Behavioral patterns
描述类或对象交互和分配责任的方式。
3.1 策略模式
对于特定的任务存在不同的算法,客户端可以在运行时根据动态上下文在算法之间切换。
应用场景:为不同的实现算法构造抽象接口,利用delegation,运行时动态传入client倾向的算法类实例
如上图所示,在使用ShoppingCart
中的pay方法时,可以根据需要传入算法策略的类型,从而实现不同的操作
优点:
- 开闭原则:策略模式遵循开闭原则(OCP),允许你在不修改现有代码的情况下引入新的策略。新策略的添加不会影响到现有的策略类和上下文类。
- 消除条件判断:策略模式通过使用多态消除了在客户端代码中使用条件判断来选择算法的需求。客户端代码不需要通过条件语句来决定使用哪种算法,而是通过策略接口调用对应的算法。
- 提高代码的灵活性和可维护性:由于策略模式将算法封装在独立的类中,算法的实现可以独立于其上下文类进行修改。这使得代码更易于理解、维护和扩展。
缺点:
- 增加对象数量:策略模式会引入大量的策略类,如果策略的数量很多,类的数量也会显著增加。这可能导致代码库变得复杂,管理起来更困难。
- 客户端必须了解不同的策略:客户端必须知道不同策略之间的区别,并且需要了解如何选择合适的策略。这增加了客户端代码的复杂性。
3.2 模板模式
做事情的步骤一样,但具体方法不同
应用场景:共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现
优点:实现了代码的复用,减少冗余代码量
缺点:基类中定义的算法骨架是固定的,子类只能修改其中的部分步骤。如果需要修改算法的整体结构,必须修改基类,这可能违背开闭原则(OCP)。
3.3 迭代器模式
客户端希望遍历被放入容器/集合类的一组ADT对象,无需关心容器的具体类型
应用场景:让自己的集合类实现Iterable接口,并实现自己的独特Iterator
迭代器(hasNext, next, remove),允许客户端利用这
个迭代器进行显式或隐式的迭代遍历
以下是代码示例
public class Pair<E> implements Iterable<E> {private final E first, second;public Pair(E f, E s) { first = f; second = s; }public Iterator<E> iterator() {return new PairIterator();}private class PairIterator implements Iterator<E> {private boolean seenFirst = false, seenSecond = false;public boolean hasNext() { return !seenSecond; }public E next() {if (!seenFirst) { seenFirst = true; return first; }if (!seenSecond) { seenSecond = true; return second; }throw new NoSuchElementException();}public void remove() {throw new UnsupportedOperationException();}}
}
3.4 Visitor模式
将数据和作用于数据上的某种特定操作分离开来
应用场景:为ADT预留一个将来可扩展功能的“接入点”,外部实现的功能代码可以在不改变ADT本身的情况下通过delegation接入ADT
优点:
- 易于增加新的操作:通过添加新的访问者类,可以在不修改对象结构的情况下定义新的操作。这使得系统更易于扩展,符合开放/封闭原则(OCP)。
- 集中相关行为:访问者模式将相关的行为集中在一个访问者类中,而不是分散在对象类中。这使得行为更容易理解和维护。
缺点:
违反单一职责原则:访问者模式将多个不相关的操作集中到访问者类中,可能违反单一职责原则。每个访问者类通常实现多个方法,这些方法可能具有不同的目的和逻辑。
相关文章:

面向可复用性和可维护性的设计模式 课程学习总结
什么是设计模式 设计模式:在软件设计中给定上下文中常见问题的通用的、可重用的解决方案。 设计模式分类 1. 创建型模式——Creational patterns 关注对象创建的过程 1.1 工厂方法模式 定义用于创建对象的接口,但让子类决定要实例化哪个类。工厂方…...

修复谷歌 AdSense 的 Ads.Txt 无效的有收益损失风险提示
明月的 AdSense 账号后台一直都有“有收益损失风险 - 您需要纠正 ads.txt 文件存在的一些问题,以免严重影响您的收入。”的提示长达一年多了,这次重新开始投放谷歌 AdSense 广告后感觉需要解决掉这个问题了,因为已经全站使用了 CloudFlare&am…...
使用向量叉乘,来计算一个点到一条线的距离
1. 使用向量叉乘,来计算一个点到一条线的距离 如果说一条线段的两个端点坐标分别是,A,B点,到线段外一点P的距离。 我们可以把,这三个点连接起来,得到一个三角形,此时的步骤就是这样的 计算这个…...
学习笔记——交通安全分析02
目录 前言 当天学习笔记整理 绪论 结束语 前言 #随着上一轮SPSS学习完成之后,本人又开始了新教材《交通安全分析》的学习 #整理过程不易,喜欢UP就点个免费的关注趴 当天学习笔记整理 绪论 美国在道路设施安全改善过程中,形成了数据基…...

pytest-sugar插件:对自动化测试用例加入进度条
摘要 在自动化测试过程中,测试进度的可视化对于开发者和测试工程师来说非常重要。本文将介绍如何使用pytest-sugar插件来为pytest测试用例添加进度条,从而提升测试的可读性和用户体验。 1. 引言 自动化测试是软件开发过程中不可或缺的一部分ÿ…...

AI大模型的口语练习APP
开发一个使用第三方大模型的口语练习APP涉及多个步骤,从需求分析到部署上线。以下是详细的开发流程和关键步骤,通过系统化的流程和合适的技术选型,可以有效地开发出一个功能丰富、用户体验良好的口语练习APP。北京木奇移动技术有限公司&#…...
Elasticsearch 详细介绍和经典应用
Elasticsearch是一个开源的分布式搜索和分析引擎,它建立在Apache Lucene搜索引擎库之上,提供了一个分布式、多租户的全文搜索引擎,能够实时地存储、检索和分析大规模的数据。以下是关于Elasticsearch的详细介绍和经典应用: 详细介…...

GEC210编译环境搭建
一、下载编译工具链 下载:点击跳转 二、解压到 /usr/local/arm 目录 sudo mv gec210.zip /usr/local/arm cd /usr/local/arm sudo unzip gec210.zip 三、添加到环境变量 PATH/usr/local/arm/arm-cortex_a8-linux-gnueabi-4.7.3/bin:$PATH 四、测试验证 在终端…...

Mysql中表之间的关系
表之间的关系 一对一、多对一(其实就是主从关系,在从表中设置一个外键关联上主表)、多对多关系(需要一个中间表,设置两个外键,分别关联到两个表的主键) 比如订单和商品之间:一个订单…...

文心智能体大赛:百度文心智能体平台初体验
写在前面 博文内容涉及:文心智能体大赛:文心智能体初体验理解不足小伙伴帮忙指正 😃,生活加油 我徒然忘记了热闹,却来不及悟透真正的清冷(《四喜忧国》) 前言 徒然忘记了热闹,却来不及悟透真正的清冷(《四喜忧国》),在…...

AI数据面临枯竭
Alexandr Wang:前沿研究领域需要大量当前不存在的数据,未来会受到这个限制 Alexandr Wang 强调了 AI 领域面临的数据问题。 他指出,前沿研究领域(如多模态、多语言、专家链式思维和企业工作流)需要大量当前不存在的数…...

2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(中):订阅智能体OSS实现
传送门: 《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(上):MetaGPT安装、单智能体开发》《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(下)&…...

LoadBalancer
一、手写随机负载均衡 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><!--引入nacos discovery--> <dependency><groupId>com…...
【栈】Leetcode 71. 简化路径【中等】
简化路径 给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 ‘/’ 开头),请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中,一个点(.)表示当前目录本身&am…...

简单操作一单利润500+,最新快手缺货赔付玩法,【找店教程+详细教程】
在如今快速变化的时代,寻找充满创新的收入来源已经成为了一种趋势。这不仅是为了实现财务的自由,更是为了在生活中拥有更多的选择权。一项革新的实践——利用手机进行快手缺货赔付单号的操作,已经成为许多人稳定“下车”的一个新途径。 据了…...

【软件设计师】先导
一、考试科目: 上午:计算机与软件工程知识,考试时间150min,75空单选题(不一定一题一空) 下午:软件设计,考试时间150分钟,问答题,6道只做5大题(前四…...

npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
提示:我解决这个bug跟别人思路可能不太一样,因为我是之前好用,换个项目就不好使了,倦了 文章目录 前言项目场景:解决方案:下载 nvm安装 nvm重新下载所需Node 版本nvm常用命令 前言 提示:这里可…...
如何用 MoonBit 实现 diff?
你使用过 Unix 下的小工具 diff 吗? 没有也没关系,简而言之,它是一个比对两个文本文件之间有什么不同之处的工具。它的作用不止于此,Unix 下还有一个叫 patch 的小工具。 时至今日,很少有人手动为某个软件包打补丁了…...
opencl色域变换,处理传递显存数据
在使用ffmpeg解码后的多路解码数据非常慢,还要给AI做行的加速方式是在显存处理数据,在视频拼接融合产品的产品与架构设计中,提出了比较可靠的方式是使用cuda,那么没有cuda的显卡如何处理呢 ,比较好的方式是使用opencl来…...

COD论文笔记 Boundary-Guided Camouflaged Object Detection
动机 挑战性任务:伪装物体检测(COD)是一个重要且具有挑战性的任务,因为伪装物体往往与背景高度相似,使得准确识别和分割非常困难。现有方法的不足:现有的深度学习方法难以有效识别伪装物体的结构和细节&am…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...