23设计模式详解「全23种」

✍️作者简介:小北编程(专注于HarmonyOS、Android、Java、Web、TCP/IP等技术方向)
🐳博客主页:开源中国稀土掘金51cto博客博客园知乎简书慕课网CSDN
🔔如果文章对您有一定的帮助请👉关注✨、点赞👍、收藏📂、评论💬。
🔥如需转载请参考【转载须知】

设计模式介绍

在软件开发领域,设计模式是一种被广泛接受的最佳实践,旨在解决常见的设计问题。设计模式的应用能够提高代码的灵活性、可维护性和可扩展性。在本文中,我们将探讨23种经典的设计模式,这些设计模式被分为创建型、结构型和行为型三个主要类别。通过深入了解这些设计模式,我们可以更好地理解如何应对各种软件设计挑战,并在项目中更加高效地应用它们。

一、什么是设计模式

设计模式是为了解决软件开发中特定问题而提出的一系列解决方案或思路。这些方案旨在提高代码的可重用性、可扩充性、可维护性以及灵活性。通过采用设计模式,我们追求实现高内聚和低耦合的代码结构。高内聚意味着相关的代码组织在一起,形成一个紧密的单元,而低耦合则表示模块之间的依赖关系较弱,使得系统更易于理解、修改和扩展。设计模式的应用有助于提升软件开发的效率,促使开发人员以一种经验丰富、通用的方式来解决常见问题,从而构建更健壮、可维护的代码基础。

二、设计模式表述

当涉及到设计模式时,了解每个模式的用途、结构和示例是很重要的。以下是一份设计模式的简要介绍,以表格样式呈现:

设计模式描述示例
单例模式 (Singleton)确保类只有一个实例,并提供全局访问点。配置管理、日志管理等
工厂模式 (Factory)一个工厂类根据传入的参量决定创建出哪一种产品类的实例。java.util.CalendargetInstance() 方法
抽象工厂模式 (Abstract Factory)创建相关或依赖对象的家族,而无需明确指定具体类。javax.xml.parsers.DocumentBuilderFactory
建造者模式 (Builder)封装一个复杂对象的创建过程,并可以按步骤构造。java.lang.StringBuilderjava.lang.StringBuffer
原型模式 (Prototype)通过复制现有的实例来创建新的实例。java.lang.Objectclone() 方法
装饰器模式 (Decorator)动态地给对象添加额外的责任。java.io 中的各种流实现
代理模式 (Proxy)控制对对象的访问。java.lang.reflect.Proxyjava.rmi.*
桥接模式 (Bridge)将抽象部分和它的实现部分分离,使它们都可以独立变化。java.awt 中的窗口和操作系统的实现
适配器模式 (Adapter)允许接口不兼容的类能够一起工作。java.util.Arrays 中的 asList() 方法
组合模式 (Composite)将对象组合成树形结构以表示“部分-整体”的层次结构。javax.swing.JComponentjava.awt.Container
外观模式 (Facade)提供一个简化的接口,隐藏系统的复杂性。javax.faces.context.FacesContext
享元模式 (Flyweight)通过共享尽可能多的相似对象来最小化内存使用或计算开销。java.lang.Integerjava.lang.String 的缓存
策略模式 (Strategy)定义一系列算法,把它们封装起来,并且使它们可以相互替换。java.util.Comparator 接口
模板方法模式 (Template Method)定义算法结构,而将一些步骤延迟到子类实现。java.util.Collections 中的排序算法
观察者模式 (Observer)对象间的一对多的依赖关系。java.util.Observerjava.util.Observable
仲裁者模式 (Mediator)用一个中介对象来封装一系列的对象交互。java.util.Timerjava.util.TimerTask
备忘录模式 (Memento)在不破坏封装的前提下,保持对象的内部状态。java.util.Date 中的 clone() 方法
解释器模式 (Interpreter)给定一个语言,定义它的文法的一种表示,并定义一个解释器。正则表达式的解析
状态模式 (State)允许一个对象在其对象内部状态改变时改变它的行为。java.awt.Component 中的状态管理
责任链模式 (Chain of Responsibility)将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。java.util.logging.Logger 中的日志记录链
访问者模式 (Visitor)不改变数据结构的前提下,增加作用于一组对象元素的新功能。javax.lang.model.element.ElementScanner6
中介者模式 (Mediator)用一个中介对象来封装一系列的对象交互。java.awt.Container 中的事件处理机制
命令模式 (Command)将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。java.util.Timerjava.util.TimerTask

请注意,这只是每个模式的简要介绍,每个模式都有详细的用例和实现细节。深入学习设计模式时,建议查阅相关的设计模式书籍或文档。

三、设计模式分类

设计模式分为三大类分别为:创建型模式、结构型模式、行为型模式
在这里插入图片描述设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。每个类别包含一系列设计模式,用于解决不同类型的问题。

1. 创建型模式(Creational Patterns):

  • 单例模式(Singleton Pattern): 保证一个类只有一个实例,并提供一个全局访问点。
  • 工厂模式(Factory Pattern): 定义一个创建对象的接口,但让子类决定实例化哪个类。
  • 抽象工厂模式(Abstract Factory Pattern): 提供一个接口,用于创建相关或依赖对象的家族,而无需指定具体类。
  • 建造者模式(Builder Pattern): 将一个复杂对象的构建过程与其表示分离,使同样的构建过程可以创建不同的表示。
  • 原型模式(Prototype Pattern): 通过复制现有对象来创建新对象,避免了直接使用 new 运算符创建对象。

2. 结构型模式(Structural Patterns):

  • 适配器模式(Adapter Pattern): 将一个类的接口转换成客户希望的另一个接口。
  • 装饰器模式(Decorator Pattern): 动态地给对象添加额外的职责。
  • 代理模式(Proxy Pattern): 为其他对象提供一种代理以控制对这个对象的访问。
  • 桥接模式(Bridge Pattern): 将抽象部分与它的实现部分分离,使它们都可以独立变化。
  • 组合模式(Composite Pattern): 将对象组合成树形结构以表示“部分-整体”的层次结构。
  • 外观模式(Facade Pattern): 提供了一个统一的接口,用来访问子系统中的一群接口。
  • 享元模式(Flyweight Pattern): 通过共享技术来有效地支持大量细粒度的对象。

3. 行为型模式(Behavioral Patterns):

  • 策略模式(Strategy Pattern): 定义一系列算法,使它们可以互相替换,而不影响客户端。
  • 模板方法模式(Template Method Pattern): 定义一个算法的骨架,而将一些步骤延迟到子类中。
  • 观察者模式(Observer Pattern): 定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖它的对象都得到通知。
  • 迭代器模式(Iterator Pattern): 提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部表示。
  • 责任链模式(Chain of Responsibility Pattern): 将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求。
  • 命令模式(Command Pattern): 将请求封装成一个对象,从而允许用不同的请求对客户进行参数化。
  • 备忘录模式(Memento Pattern): 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
  • 状态模式(State Pattern): 允许对象在其内部状态改变时改变其行为。
  • 访问者模式(Visitor Pattern): 表示一个作用于某对象结构中的各元素的操作,它使你可以定义作用于一个对象结构的新操作。

这些设计模式为软件开发提供了一套通用的解决方案,开发者可以根据问题的性质选择合适的模式,提高代码的可维护性和可扩展性。设计模式并非固定不变的规定,而是一种经验的总结,在实际开发中可以根据需要适度灵活运用。

三、设计模式的几种原则(七种OOP原则)

设计模式并不是僵化的规则,而是一种通用的经验和思想的体现。在使用设计模式时,可以参考一些基本原则,以确保它们的有效应用。以下是几种与设计模式相关的原则:
对不起,存在一些混淆。在软件工程中,有两个主要的七大原则概念,其中一个是 SOLID 原则,另一个是经典的设计原则。我会为你澄清这两个概念:

SOLID 原则(面向对象编程的基本设计原则):

1. 单一职责原则 (Single Responsibility Principle - SRP):
  • 概念: 一个类应该只有一个引起变化的原因,即一个类应该只有一个职责。
  • 应用: 将一个类的多个职责拆分成不同的类,以提高可维护性和灵活性。
2. 开闭原则 (Open/Closed Principle - OCP):
  • 概念: 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭,即可以通过扩展现有代码来添加新功能,而不是修改已有的代码。
  • 应用: 使用抽象和接口,通过扩展而不是修改现有类来实现新功能。
3. 里氏替换原则 (Liskov Substitution Principle - LSP):
  • 概念: 子类必须能够替换掉它们的基类,即基类能出现的地方,子类就可以出现。
  • 应用: 子类应该继承基类的行为,并且不应该引入新的行为,确保替换时不会破坏程序的正确性。
4. 依赖倒置原则 (Dependency Inversion Principle - DIP):
  • 概念: 高层模块不应该依赖于底层模块,两者都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
  • 应用: 使用接口和抽象类,将系统的高层模块与底层模块解耦。
5. 接口隔离原则 (Interface Segregation Principle - ISP):
  • 概念: 一个类不应该被强迫实现它用不到的接口,即客户端不应该强制依赖它们不使用的方法。
  • 应用: 将庞大的接口拆分成较小的、更专注的接口,以便类只需要实现它们真正需要的部分。

经典的设计原则(Design Principles):

1. 迪米特法则 (Law of Demeter 或 Least Knowledge Principle - LoD/PLK):
  • 概念: 一个对象应该对其他对象有最少的了解,即一个类不应该直接调用其他对象的内部细节。
  • 应用: 通过尽量减少对象之间的直接交互,降低耦合性,提高系统的灵活性。
2. 合成/聚合复用原则 (Composite/Aggregate Reuse Principle - CARP):
  • 概念: 优先使用合成/聚合,而不是继承。通过将对象组合在一起,达到复用的目的。
  • 应用: 使用对象的组合关系,而不是通过继承来达到代码重用,避免继承链的过度膨胀。

这些原则不仅对设计模式的应用有指导作用,同时也是面向对象设计的基本原则,有助于构建更灵活、可维护和可扩展的软件系统。

四、设计模式的关系

设计模式之间的关系并不是绝对的,而是取决于具体的使用场景和问题要求。开发人员可以根据实际情况选择适当的设计模式或组合多个设计模式来解决问题。设计模式的组合和应用可以形成更加复杂、灵活的软件设计结构。

设计模式关系图

在这里插入图片描述
设计模式之间存在着多种关系,这些关系有助于理解它们在不同情境下的应用。以下是设计模式之间常见的几种关系:

1. 创建型模式之间的关系:

  • 工厂方法模式与抽象工厂模式: 抽象工厂模式是工厂方法模式的一种扩展,它提供一组相关或相互依赖的工厂类。
  • 建造者模式与抽象工厂模式: 抽象工厂模式关注对象组合,而建造者模式关注对象的构建步骤。

2. 结构型模式之间的关系:

  • 适配器模式与装饰器模式: 适配器模式用于使接口兼容,而装饰器模式用于动态地添加或覆盖对象的行为。
  • 代理模式与适配器模式: 代理模式和适配器模式都允许一个对象包装另一个对象,但目的不同。代理模式提供了一种控制对对象的访问的方式,而适配器模式提供了不同接口之间的兼容性。

3. 行为型模式之间的关系:

  • 观察者模式与发布-订阅模式: 这两者都用于处理对象之间的发布-订阅关系,但观察者模式通常是一对多的关系,而发布-订阅模式可以是多对多的关系。
  • 命令模式与策略模式: 命令模式将请求封装成对象,而策略模式将算法封装成对象。

4. 设计模式与 SOLID 原则之间的关系:

  • 上面提到的单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则和合成/聚合复用原则是设计模式的设计原则基础。设计模式通常遵循这些原则,以确保系统的灵活性、可维护性和可扩展性。

五、设计模式的优缺点

设计模式的应用可以提供许多优势,但同时也存在一些潜在的缺点。

优点

  1. 可重用性: 设计模式提供了可重用的解决方案,可以在不同项目和场景中使用。
  2. 可维护性: 使用设计模式可以使代码更易于理解和维护,降低系统的复杂性。
  3. 可扩展性: 设计模式使系统更容易扩展,适应新的需求和变化。

缺点

  1. 学习成本: 初学者可能需要一些时间来理解和熟悉设计模式的概念和应用。
  2. 过度使用: 不合理的使用设计模式可能导致代码过于复杂,增加维护难度。

六、设计模式总结

设计模式是软件开发中的宝贵经验总结,通过提供通用的解决方案,使得开发人员能够更加高效地应对不同的设计问题。在本文中,我们简要介绍了设计模式的概念,分类以及它们的优缺点。深入理解和熟练应用这些设计模式,将有助于提高软件系统的质量和可维护性。在实际项目中,合理地选择和灵活运用设计模式,将为软件开发带来长远的益处。

这个结构可以帮助你有条理地介绍每个设计模式,展示其应用场景和优劣势,最终给读者一个全面的认识。

在这里插入图片描述

♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠

无论是哪个阶段,坚持努力都是成功的关键。不要停下脚步,继续前行,即使前路崎岖,也请保持乐观和勇气。相信自己的能力,你所追求的目标定会在不久的将来实现。

编码不仅仅是一项技能,更是一种态度。愿你的代码生涯充满创造力和乐趣,愿你的程序梦想绽放光芒。加油,未来的代码之星!

  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小北编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值