设计模式之GoF23介绍
深入探讨设计模式:构建可维护、可扩展的软件架构
- 一、设计模式的背景
- 1.1 什么是设计模式
- 1.2 设计模式的历史
- 二、设计模式的分类
- 2.1 创建型模式
- 2.2 结构型模式
- 2.3 行为型模式
- 三、七大设计原则
- 四、设计模式关系
- 结论 :rocket: :rocket: :rocket:

在软件开发领域,设计模式是一种用于解决特定问题的经验性的、可重用的设计思想。设计模式不仅是面向对象编程(OOP)的基石,更是构建可维护、可扩展软件架构的重要工具。本文将深入探讨设计模式,包括其概念、历史、分类、七大设计原则以及设计模式关系。
一、设计模式的背景
1.1 什么是设计模式
设计模式(Design pattern)是对软件设计中普遍存在的问题的通用解决方案。它们提供了一种在特定上下文中解决问题的方法,是经过验证的、可复用的设计思想。设计模式不是代码或库,而是一种更高层次的抽象,它帮助开发者更好地组织和理解代码。
通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目的是实现代码的高内聚和低耦合。
1.2 设计模式的历史
设计模式的概念最早由计算机科学家Christopher Alexander引入,他在建筑领域中提出了“模式语言”的概念。后来,Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides等四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中将设计模式引入到软件开发领域。这本书通常被称为GoF(Gang of Four,四人组)书籍,成为设计模式领域的经典之作。
二、设计模式的分类

2.1 创建型模式
对象实例化的模式,创建型模式用于解耦对象的实例化过程。
- 单例模式:某个类智能有一个实例,提供一个全局的访问点。
- 工厂方法模式:一个工厂类根据传入的参量决定创建出哪一种产品类的实例。
- 抽象工厂模式:创建相关或依赖对象的家族,而无需明确指定具体类。
- 建造者模式:封装一个复杂对象的创建过程,并可以按步骤构造。
- 原型模式:通过复制现有的实例来创建新的实例。
2.2 结构型模式
把类或对象结合在一起形成一个更大的结构。
- 装饰器模式:动态的给对象添加新的功能。
- 代理模式:为其它对象提供一个代理以便控制这个对象的访问。
- 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
- 适配器模式:将一个类的方法接口转换成客户希望的另一个接口。
- 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。
- 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。
- 享元模式:通过共享技术来有效的支持大量细粒度的对象。
2.3 行为型模式
类和对象如何交互,及划分责任和算法。
- 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。
- 模板方法模式:定义一个算法结构,而将一些步骤延迟到子类实现。
- 命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
- 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。
- 观察者模式:对象间的一对多的依赖关系。
- 仲裁者模式:用一个中介对象来封装一系列的对象交互。
- 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。
- 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。
- 建造者模式:允许一个对象在其对象内部状态改变时改变它的行为。
- 责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
- 访问者模式:不改变数据结构的前提下,增加作用于一组对象元素的新功能。
三、七大设计原则

设计模式的核心是一系列通用的原则,这些原则有助于制定良好的软件设计方案。以下是七大设计原则:
-
单一职责原则 (Single Responsibility Principle, SRP)
- 一个类应该只有一个引起变化的原因。换句话说,一个类只负责一个功能领域。
-
开放/封闭原则 (Open/Closed Principle, OCP)
- 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。即,我们可以通过添加新的代码来扩展功能,而不必修改已有的代码。
-
里氏替换原则 (Liskov Substitution Principle, LSP)
- 子类必须能够替换其基类而不影响程序的正确性。换句话说,如果一个软件实体使用了一个基类,那么替换成其子类也不应该导致程序出错。
-
依赖倒置原则 (Dependency Inversion Principle, DIP)
- 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
-
接口隔离原则 (Interface Segregation Principle, ISP)
- 不应该强迫一个类实现它不需要的接口。一个类对其他类的依赖应该建立在最小的接口上。
-
合成/聚合复用原则 (Composite/Aggregate Reuse Principle, CARP)
- 首选使用合成/聚合而不是继承来达到复用的目的。即,通过将现有的类组合在一起创建新的功能,而不是通过继承。
-
迪米特法则 (Law of Demeter, LoD)
- 一个对象应该对其他对象有最少的了解。一个类不应该直接调用其它对象的内部方法,而应该通过一个中间对象进行调用。
四、设计模式关系

结论 🚀 🚀 🚀
设计模式是软件开发中的有力工具,通过提供经验丰富的解决方案,帮助开发者构建可维护、可扩展的软件系统。然而,应该在实践中谨慎使用,根据具体情况灵活运用,以避免过度工程和不必要的复杂性。设计模式不仅仅是一种技术,更是一种艺术,需要在实践中不断体悟!
相关文章:
设计模式之GoF23介绍
深入探讨设计模式:构建可维护、可扩展的软件架构 一、设计模式的背景1.1 什么是设计模式1.2 设计模式的历史 二、设计模式的分类2.1 创建型模式2.2 结构型模式2.3 行为型模式 三、七大设计原则四、设计模式关系结论 :rocket: :rocket: :rocket: 在软件开发领域&…...
UDP协议实现群聊
服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…...
lombok原理 @Slf4j 怎么生成get set log
Lombok是一种Java库,通过注解的方式提供了许多有用的功能,包括生成Getter、Setter、日志等。Slf4j注解是Lombok中的一种,它用于自动生成日志记录器(Logger)。 下面简要介绍一下Lombok的原理,以及Slf4j注解…...
【目标检测】进行实时检测计数时,在摄像头窗口显示实时计数个数
这里我是用我本地训练的基于yolov8环境的竹签计数模型,在打开摄像头窗口增加了实时计数显示的代码,可以直接运行,大家可以根据此代码进行修改,其底层原理时将检测出来的目标的个数显示了出来。 该项目链接:【目标检测…...
SpringBoot第56讲:SpringBoot集成文件 - 集成EasyExcel之Excel导入导出
集成EasyExcel之Excel导入导出 EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。它能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。它是基于POI来封装实现的,主要解决其易用性,封装性和性能问题。本文是SpringBoot第…...
python3安装lifelines
目录 一、环境 二、安装lifelines 出现问题 三、测试导入 一、环境: jupyter notebook中新建ipynb文件 二、安装lifelines pip install --upgrade --no-deps githttps://github.com/CamDavidsonPilon/lifelines.git出现问题: 缺少模块autograd、f…...
shell命令学习(1)——(待完善)
explainshell.com shell统计当前文件夹下的文件个数、目录个数Linux之shell常用命令(三) sort(排序)、uniq(处理重复字符) linux中shell将换行输入到文件中 shell脚本,将多行内容写入文件中 f…...
机器的深度强化学习算法可以被诱导
设计一个好的奖励函数是机器深度强化学习算法的关键之一。奖励函数用于给予智能体(机器)在环境中采取不同行动时的反馈信号,以指导其学习过程。一个好的奖励函数应该能够引导智能体朝着期望的行为方向学习,并尽量避免潜在的问题&a…...
学生成绩管理系统(Java)
开发环境: Windows 11 IDEA 2021.3.3 需求: package com.it.neu;import java.util.ArrayList; import java.util.Scanner;import static java.time.Clock.system;class Student { //创建学生类private String Stu_name;private String Stu_id;public Student(String id, S…...
Modbus数据采集模块是什么?
随着工业自动化的快速发展,数据采集已成为现代工厂不可或缺的一环。在众多通信协议中,Modbus因其开放、简单、可靠的特点而广受青睐。那么,什么是Modbus数据采集模块,它又有哪些应用呢? 一、什么是Modbus数据采集模块…...
【网络安全】下载并安装 kali 的虚拟机 版本
kali虚拟机版本的下载地址:Get Kali | Kali Linux 下载完成后,解压,双击.vmx打开,即可完成kali在虚拟机中的安装和配置。 默认账户和密码都为kali...
JREBEL 热部署原理
JRebel(Java Rebel)是一个Java开发工具,它提供了一种在不重启应用服务器的情况下进行Java应用程序的热部署的方式。通过JRebel,开发者可以在修改Java代码后立即看到变化,加速开发和调试过程。 以下是JRebel实现热部署…...
履带吊,笔记
0.前言 履带吊使用了与传统的门桥式起重机不同的技术路线。因为它是移动式设备,所以它的动力是燃油发动机。为了精确调控升降。它的整套动力系统似乎采用了某种液压传动系统。履带吊国内也有生产商。但是下文中,还是从国外的一款产品说起。这款产品的pd…...
WPF转换器Convert
图像名称转换器ImageNameConverter,用于在数据绑定中将图像路径转换为图像文件名。 转换器的代码如下: using System; using System.Globalization; using System.IO; using System.Windows.Data;namespace ImageConverter {public class ImageNameCon…...
【刷题】【力扣牛客】反转链表的五种方式——Java
文章目录 前言方法一:构造新链表(构造新节点)方法二:构造新链表(不构造新节点)方法三:递归方法四:双指针方法五:遍历总结 力扣题目链接:206. 反转链表 牛客题…...
使用Java网络编程,窗口,线程,IO,内部类等实现多人在线聊天1.0
1.整体思路 思路图 整体思路如上: 涉及知识点:线程网络编程集合IO等 TCP 协议 2.代码实现过程 服务端 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import jav…...
相关教程test
第一天 主题:LLM初体验 上午: 一,大模型的发展背景和模型演进 数据增长和算力提升LSTM到BERT到LLM的参数巨变最新paper解读(根据授课时间,选择最近的核心paper进行解读) 二,大模型核心阶段…...
mysql知识分享(包含安装卸载)(一)
如果博客有错误,请佬指正。 目录 注意:打开cmd时要有管理员身份打开,重要 为何使用数据库? 数据库的相关概念 关系型数据库 关系型数据库设计规则 表,记录,字段 表的关联关系 一对一关联 一对多关系 …...
Google Guava 反射工具使用详解
文章目录 反射类操作方法操作字段操作获取注解 反射 在 Guava 中,反射(Reflection)模块提供了一些用于简化反射操作的工具类和方法。通过 Guava 的反射模块,您可以方便地进行类、方法、字段的操作、获取注解信息等。下面详细介绍…...
MySql MVCC 详解
注意以下操作都是以InnoDB引擎为操作基准。 一,前置知识准备 1,MVCC简介 MVCC 是多版本并发控制(Multiversion Concurrency Control)的缩写。它是一种数据库事务管理技术,用于解决并发访问数据库的问题。MVCC 通过创…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...
Python学习(8) ----- Python的类与对象
Python 中的类(Class)与对象(Object)是面向对象编程(OOP)的核心。我们可以通过“类是模板,对象是实例”来理解它们的关系。 🧱 一句话理解: 类就像“图纸”,对…...
DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...
