面向可复用性和可维护性的设计模式 课程学习总结
什么是设计模式
设计模式:在软件设计中给定上下文中常见问题的通用的、可重用的解决方案。
设计模式分类
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…...
告别Appium!用Python+UIAutomator2搞定Android自动化测试(附完整环境搭建与实战代码)
PythonUIAutomator2:Android自动化测试的高效实践指南 在移动应用测试领域,效率与稳定性始终是工程师们追求的核心目标。传统方案如Appium虽然功能全面,但在执行速度和资源消耗方面往往难以满足高频测试需求。本文将带您探索基于Python和UIA…...
5步完美解决Windows 10 PL2303驱动兼容性问题:完整实施方案指南
5步完美解决Windows 10 PL2303驱动兼容性问题:完整实施方案指南 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 在Windows 10系统中使用PL2303 USB转串口设…...
如何在5分钟内免费搭建工业级OpenPLC虚拟控制器
如何在5分钟内免费搭建工业级OpenPLC虚拟控制器 【免费下载链接】OpenPLC Software for the OpenPLC - an open source industrial controller 项目地址: https://gitcode.com/gh_mirrors/op/OpenPLC OpenPLC是一款功能强大的开源虚拟PLC(可编程逻辑控制器&a…...
yuzu模拟器:在PC上完美运行Switch游戏的终极解决方案
yuzu模拟器:在PC上完美运行Switch游戏的终极解决方案 【免费下载链接】yuzu 任天堂 Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/yu/yuzu 想要在电脑上体验任天堂Switch游戏的魅力吗?yuzu模拟器作为目前最成熟的开源Switch模拟…...
终极指南:5步精通开源网页版三国杀无名杀
终极指南:5步精通开源网页版三国杀无名杀 【免费下载链接】noname 项目地址: https://gitcode.com/GitHub_Trending/no/noname 想要随时随地畅玩经典的三国杀卡牌游戏吗?无名杀作为当前最受欢迎的开源网页版三国杀,让你无需下载客户端…...
清华大学学位论文LaTeX模板:告别格式烦恼的终极指南
清华大学学位论文LaTeX模板:告别格式烦恼的终极指南 【免费下载链接】thuthesis LaTeX Thesis Template for Tsinghua University 项目地址: https://gitcode.com/gh_mirrors/th/thuthesis 还在为论文格式调整而烦恼吗?清华大学thuthesis LaTeX模…...
别再手动触发ADC了!用STM32CubeMX配置定时器触发+DMA搬运,实现精准采样(附F1/F4差异说明)
STM32CubeMX定时器触发ADCDMA全自动采样实战指南 在嵌入式数据采集系统中,ADC采样的精准度和效率直接影响整个系统的性能表现。传统的手动触发方式不仅占用CPU资源,还难以保证采样间隔的一致性。本文将深入解析如何利用STM32CubeMX配置定时器触发ADC配合…...
5步掌握AMD锐龙SDT调试工具:从硬件小白到调优高手的实战指南
5步掌握AMD锐龙SDT调试工具:从硬件小白到调优高手的实战指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: http…...
UniversalUnityDemosaics:Unity游戏马赛克移除技术的深度解析与实践指南
UniversalUnityDemosaics:Unity游戏马赛克移除技术的深度解析与实践指南 【免费下载链接】UniversalUnityDemosaics A collection of universal demosaic BepInEx plugins for games made in Unity3D engine 项目地址: https://gitcode.com/gh_mirrors/un/Univers…...
终极Go性能优化工具gcvis:实时可视化GC跟踪数据完整指南
终极Go性能优化工具gcvis:实时可视化GC跟踪数据完整指南 【免费下载链接】gcvis Visualise Go program GC trace data in real time 项目地址: https://gitcode.com/gh_mirrors/gc/gcvis gcvis是一款专为Go语言开发者设计的实时垃圾回收可视化工具࿰…...
