面向可复用性和可维护性的设计模式 课程学习总结

什么是设计模式

设计模式:在软件设计中给定上下文中常见问题的通用的、可重用的解决方案。

设计模式分类

1. 创建型模式——Creational patterns

关注对象创建的过程

1.1 工厂方法模式

定义用于创建对象的接口,但让子类决定要实例化哪个类。工厂方法允许类将实例化推迟到子类。

应用场景:当client不知道要创建哪个具体类的实例,或者不想在client代码中指明要具体创建的实例时,用工厂方法。

优点:无需将特定于应用程序的类绑定到代码中。代码仅处理接口,所以它可兼容其他子类。

缺点:增加代码量,需要额外增加一个Creator类及其子类。

2. 结构型模式——Structural patterns

处理类或对象的组合

2.1 适配器模式

将某个类/接口转换为client期望的其他形式

应用场景:需要在新系统中重用一个不兼容的老组件

在这里插入图片描述

如上图所示,为了实现Shape的display方法,对先前已存在的类—LegacyRectangle中的diaplay方法进行了重用

优点:实现了对已有类的大限度复用,避免“重新造轮子”。

缺点:适配器模式会引入额外的类和代码,这可能会增加系统的复杂性。此外,适配器模式有时会被用来掩盖设计上的问题,而不是解决它们。例如,适配器可能被用来连接不兼容的接口,但这可能是由于设计不良或缺乏整体架构考虑造成的。使用适配器模式可能会使得根本问题被忽视。

2.2 装饰器模式

实现子类特性的任意组合

应用场景:想要对子类实现多个特性的堆叠

在这里插入图片描述

上图为一个应用实例,通过逐层调用装饰器进行包装,实现特性的组合

优点:

  1. 动态扩展对象功能:装饰器模式允许在运行时动态地添加功能,而无需修改对象的类。这使得可以根据需要灵活地增加或移除功能。
  2. 遵循单一职责原则:每个装饰器类都专注于一个特定的功能扩展。这使得每个类的职责更加单一和明确,易于维护和理解。
  3. 替代继承:通过组合而不是继承来扩展对象的功能,避免了类爆炸(class explosion)问题。继承会导致大量的子类,而装饰器模式则通过不同装饰器的组合来实现相同的效果。
  4. 灵活性和可组合性:多个装饰器可以组合使用,以创建复杂的功能扩展。这种组合方式提供了极大的灵活性,允许以多种方式排列和组合装饰器。
  5. 透明性:客户端可以透明地使用装饰器,而无需知道对象被装饰了。装饰器模式对客户端是透明的,客户端代码无需修改即可使用增强功能的对象。

缺点

  1. 增加代码复杂性:虽然装饰器模式提供了灵活性,但也增加了系统的复杂性。尤其是在装饰器链较长时,调试和排查问题可能变得困难。
  2. 较多的小类:由于每个具体装饰器都是一个独立的小类,这可能导致系统中类的数量增加,从而增加维护和管理的难度。

3. 行为类模式——Behavioral patterns

描述类或对象交互和分配责任的方式。

3.1 策略模式

对于特定的任务存在不同的算法,客户端可以在运行时根据动态上下文在算法之间切换。

应用场景:为不同的实现算法构造抽象接口,利用delegation,运行时动态传入client倾向的算法类实例

在这里插入图片描述

如上图所示,在使用ShoppingCart中的pay方法时,可以根据需要传入算法策略的类型,从而实现不同的操作

优点

  1. 开闭原则:策略模式遵循开闭原则(OCP),允许你在不修改现有代码的情况下引入新的策略。新策略的添加不会影响到现有的策略类和上下文类。
  2. 消除条件判断:策略模式通过使用多态消除了在客户端代码中使用条件判断来选择算法的需求。客户端代码不需要通过条件语句来决定使用哪种算法,而是通过策略接口调用对应的算法。
  3. 提高代码的灵活性和可维护性:由于策略模式将算法封装在独立的类中,算法的实现可以独立于其上下文类进行修改。这使得代码更易于理解、维护和扩展。

缺点

  1. 增加对象数量:策略模式会引入大量的策略类,如果策略的数量很多,类的数量也会显著增加。这可能导致代码库变得复杂,管理起来更困难。
  2. 客户端必须了解不同的策略:客户端必须知道不同策略之间的区别,并且需要了解如何选择合适的策略。这增加了客户端代码的复杂性。

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

优点

  1. 易于增加新的操作:通过添加新的访问者类,可以在不修改对象结构的情况下定义新的操作。这使得系统更易于扩展,符合开放/封闭原则(OCP)。
  2. 集中相关行为:访问者模式将相关的行为集中在一个访问者类中,而不是分散在对象类中。这使得行为更容易理解和维护。

缺点

违反单一职责原则:访问者模式将多个不相关的操作集中到访问者类中,可能违反单一职责原则。每个访问者类通常实现多个方法,这些方法可能具有不同的目的和逻辑。

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

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

相关文章

4.Redis之Redis的通用命令

0.Redis 实战操作 通过 redis-cli 客户端和 redis 服务器交互 涉及到很多的 redis 的命令 【redis 的命令非常非常多!!! 1.掌握常用命令(多操作多练习) 2.学会使用 redis 的文档-> 阅读文档, 是程序猿的基操!! redis 的命令非常非常多!!! 1.掌握常用命令(多操作多练习…

部署CNI网络组件+k8s多master集群部署+负载均衡

一、环境部署 主机服务 192.168.91.5 K8S集群master01192.168.91.8 K8S集群master02192.168.91.6K8S集群node01192.168.91.7K8S集群node02192.168.91.9 负载均衡nginxkeepalive01&#xff08;master&#xff09;192.168.91.10 负载均衡nginxkeepalive02&#xff08;backup&am…

编程实战:自己编写HTTP服务器(系列3:处理框架)

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 系列入口&#xff1a;编程实战…

TypeScript学习日志-第三十二天(infer关键字)

infer关键字 一、作用与使用 infer 的作用就是推导泛型参数&#xff0c;infer 声明只能出现在 extends 子语句中&#xff0c;使用如下&#xff1a; 可以看出 已经推导出类型是 User 了 二、协变 infer 的 协变会返回联合类型&#xff0c;如图&#xff1a; 三、逆变 infer…

pikachu靶场中的CSRF、SSRF通关

目录 1、CSRF介绍 2、CSRF&#xff08;get&#xff09; 3、CSRF&#xff08;post&#xff09; 4、CSRF Token 5、SSRF介绍 6、SSRF&#xff08;curl&#xff09; 7、SSRF&#xff08;file_get-content&#xff09; 8、CSRF与SSRF的区别 最近在学习CSRF、SSRF漏洞&#…

Haskell 的高阶函数(Higher-order functions)

本节继续介绍Haskell的知识&#xff0c;本节内容介绍的是高阶函数&#xff08;Higher-order functions&#xff09;的概念和应用。高阶函数是指能够接受其他函数作为参数&#xff0c;或者返回函数作为结果的函数。 Functions as values&#xff08;函数作为值&#xff09;&…

Boyer-Moore投票算法

摩尔投票法&#xff0c;又称为博耶-摩尔多数投票算法&#xff0c;是一种用于在一组数据中寻找多数元素(出现次数超过一半的元素)的算法。该算法的效率非常高&#xff0c;时间复杂度为O(n)&#xff0c;空间复杂度为O(1)&#xff0c;适合处理大数据量的情况。 步骤 首先定义两个…

飞机大战游戏实现揭秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、游戏概览与核心玩法 二、游戏模块详解 1. 游戏主循环模块 2. 创建初始化模块 三、关…

【pytorch】关于OpenCV和PIL.Image读取图片的区别

数据使用方角度 首先从pytorch出发&#xff0c;torchvision.transforms()要求传入的图像是PIL.Image格式&#xff08;通道要求是RGB格式的&#xff09;&#xff0c;另外模型处理输入要转换为[1,channel,H,W]&#xff1b; 所以最终导入torchvision.transforms()的图像格式需要转…

跟我学C++中级篇——内存屏障内存栅栏和编译器屏障以及相关

一、低级同步常见的技术术语 在一些操作系统或者计算机接口等比较原理化的书籍中&#xff0c;经常提到一些低级的同步术语&#xff0c;或者说一些同步的抽象的说法。最典型的就是内存内存屏障。不同的平台和语言有不同的叫法&#xff0c;有的叫内存栅栏或者屏障指令。它的主要…

在3090卡服务器上面进行funasr模型微调

文本记录了在3090卡上对实时asr模型进行微调的过程&#xff0c;包括数据准备、模型微调、验证微调后的模型。 一、参考文档&#xff1a; https://github.com/alibaba-damo-academy/FunASR/blob/main/examples/industrial_data_pretraining/paraformer_streaming/README_zh.md…

帝国CMS跳过选择会员类型直接注册方法

国CMS因允许多用户组注册&#xff0c;所以在注册页面会有一个选择注册用户组的界面&#xff0c;即使网站只用了一个用户组也会出现。 如果想去掉这个页面&#xff0c;直接进入注册页面&#xff0c;那么可按以下办法修改 打开 e/class/user.php 文件 查找&#xff1a; $chan…

TCP通信实现(服务端与客户端)

TCP通信实现&#xff08;服务器端) 案例 // TCP 通信的服务器端#include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h>int main() {// 1.创建socket(用于监听的套接字)int lfd socket(AF_…

Linux_CentOS7.6防火墙常用相关命令汇总(防火墙关闭与开启)

CentOS 防火墙是操作系统自带的一款网络安全工具&#xff0c;可以用于限制和管理网络流量。以下是一些 CentOS 防火墙相关的常用命令&#xff08;不常用的&#xff0c;太多了就不写了&#xff09;&#xff1a; 在centos7中用firewalld代替以前的iptables 一&#xff0c;查看防…

人脑与电脑有什么不同

人脑和计算机都是信息处理装置&#xff0c;目前人类对自己大脑的原理了解甚少。然而它们仍然有一些相似之处&#xff0c;例如都需要记忆来存储信息。人脑有些功能特性是计算机所没有的&#xff0c;且很难模拟出来&#xff0c;所以两者在原理上并不完全相同。 计算机由人类发明&…

美军配备人工智能武器的机器狗引发伦理争议

近日&#xff0c;美国海军陆战队特种作战司令部&#xff08;MARSOC&#xff09;的一项测试引发了全球关注&#xff1a;他们正在评估一种由“幽灵机器人”公司研发的最新型机器狗&#xff0c;并考虑为其配备“玛瑙工业”公司提供的武器系统。这一消息犹如在平静的湖面投下一颗石…

weixin209基于微信小程序投票评选系统的设计与实现ssm-手把手调试

weixin209基于微信小程序投票评选系统的设计与实现ssm-手把手调试 weixin209基于微信小程序投票评选系统的设计与实现ssm-手把手调试

Python 之 日志巡检脚本

脚本说明 使用Paramiko库进行SSH连接的自动化脚本&#xff0c;用于检查、配置和排除设备故障。说明如下&#xff1a; 导入所需的库&#xff1a;paramiko、json、logging和concurrent.futures。定义配置文件路径&#xff08;devices.json&#xff09;和日志文件路径&#xff0…

阿里巴巴最新研究突破:自我演化大模型,打破性能天花板

获取本文论文原文PDF&#xff0c;请在公众号【AI论文解读】留言&#xff1a;论文解读AI论文解读 原创作者 | 柏企 引言&#xff1a;自我进化的新篇章 在人工智能领域&#xff0c;大型语言模型&#xff08;LLMs&#xff09;的发展正迎来一场革命性的变革。传统的训练模式依赖…

006、API_单线程

Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库 服务&#xff0c;本节首先通过多个客户端命令调用的例子说明Redis单线程命令处理 机制&#xff0c;接着分析Redis单线程模型为什么性能如此之高&#xff0c;最终给出为什么理 解单线程模型是使用和运维Redis的…