设计模式(类的拓扑结构)(为什么会产生设计模式,以及什么是设计模式)

设计模式(类的拓扑结构)(为什么会产生设计模式,以及什么是设计模式)

这篇文章就是为了解决:

1.什么是设计模式

2.为什么会有设计模式

1.什么是设计模式

其实很多人不懂设计模式,本质上是被这个名字误导了

他压根不是什么模式

他是解决需求的类的拓扑结构

他是类和类组成的一种结构,可以用来解决需求。

2.为什么需要设计模式

其实了解设计模式

本质上,就是熟练使用类的设计

多个类之间怎么组合设计

来实现需求

对于写复杂需求,重构代码

在特定的场景有画龙点睛的作用

3.掌握设计模式实际上掌握的事什么东西

掌握的是多个类之间可以怎么连接设计

所以我们看,掌握设计模式

就是掌握多个类之间怎么设计

通过继承,组合,实现这些


设计模式不是什么模式,而是类的拓扑结构

这篇文章就想说清楚两件事:

  1. 什么是设计模式
  2. 为什么会有设计模式

一、什么是设计模式

其实很多人觉得设计模式难懂,本质上是被"模式"这个名字误导了

它压根不是什么玄妙的模式,也不是一段可以直接复制粘贴的代码库。
设计模式 = 解决特定需求的类的拓扑结构

什么叫"类的拓扑结构"?

简单说,就是若干个类通过继承、实现、组合这三种基本关系,连接成的一种特定的结构图。这个结构图是用来解决某一类重复出现的软件设计问题的。

所有 GoF 的 23 种设计模式,本质上都是这三种关系原语搭建出来的:

关系原语 代码表现 在模式中的典型角色
继承 class B extends A 模板方法模式(定义算法骨架),抽象工厂(定义产品族)
实现 class B implements I 策略模式的策略接口,观察者模式的通知接口
组合 class A { B b; } 装饰器模式中持有被装饰对象,适配器中持有被适配者

策略模式举例,它的拓扑结构非常清晰:

复制代码
       Context (上下文)                     Strategy (接口)
            │                                   ▲
            │ 组合一个 ────────────────────── 实现
            │                                   │
            ├─────────> 具体策略A              具体策略A
            ├─────────> 具体策略B              具体策略B
            └─────────> 具体策略C              具体策略C

这个拓扑的特点是:星型 + 组合。上下文只依赖接口,不依赖具体策略类。要增加新策略,只需要再增加一个实现类,不改动上下文。你看,结构决定了能力。

所以,别再被"模式"两个字唬住了。
设计模式就是一张张类与类如何连接的蓝图


二、为什么需要设计模式

2.1 历史原因:大规模面向对象编程后的必然产物

1994 年,四位作者(Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides,简称 GoF)出版了《设计模式:可复用面向对象软件的基础》。

他们并没有"发明"这些模式,而是总结了 23 个已经在大规模系统中被反复验证有效的类的组织结构

为什么是 1994 年?

因为 80--90 年代,C++ 和 Smalltalk 等面向对象语言开始普及,大家都在用"类"编程。但很多人只是把类当成"带方法的 C 结构体",不知道怎么组织多个类之间的协作。

大型软件频繁出现崩溃、维护困难,业界急需一套类与类协作的标准走法

设计模式的本质不是什么学院派空想,而是大规模面向对象编程产生的避坑指南

2.2 根本原因:管理变化,降低修改成本

更深一层的原因是软件世界的一个根本矛盾:

需求总是在变化,但代码的修改成本很高。

一开始写代码,你可能只用两三个类,直接互相 new、直接调用。这就像一个临时搭起来的棚屋,很快、很随意。

但当需求不断增加(比如要支持新的支付方式、新的导出格式、新的UI风格),直接修改原有类会越来越危险:改一处,炸一片。

于是前辈程序员们发现:如果提前让类之间形成某种固定的、松耦合的连接关系 (比如不直接 new,而是通过一个工厂;不直接调用,而是通过一个观察者列表),就能让未来的修改变得局部化、可插拔。

设计模式不是追求结构美,而是管理变化、降低修改成本的工具。

2.3 从"代码坏味道"到"模式重构":一个对比表

理解"为什么需要",最好的方式是看一个反例和一个正例的对比。下面这个表格,展示了常见坏味道与对应模式拓扑的关系:

代码坏味道 拓扑问题 使用的模式 拓扑变化
大量 if-else 根据类型做不同事情 逻辑与调用者强耦合 策略模式 从过程式分支 → 星型拓扑(接口+多个实现)
需要给一个类动态增加职责(缓存、日志等) 继承会导致类爆炸 装饰器模式 链式拓扑:装饰器与被装饰者实现同一接口,且装饰器组合另一个该接口对象
多个模块需要监听某个对象的状态变化 直接调用导致硬编码依赖 观察者模式 星型 + 单向依赖:主题维护观察者列表,观察者实现统一接口
需要适配一个第三方库的接口 接口不匹配,改不动三方库 适配器模式 菱形拓扑:客户端依赖目标接口,适配器实现目标接口并持有被适配者

设计模式不是炫技,而是对特定坏味道的标准手术方案。


三、掌握设计模式,实际上掌握的是什么

很多人学完设计模式后,只会背名字和类图,到了实际写代码还是不会用。

因为真正的掌握,不是记住了名词,而是下面三层能力:

层次 名称 具体内容 例子
L1 识别与匹配 看到代码/需求,能认出该用哪个模式 "这里有多个算法需要切换 → 策略模式"
L2 拓扑实现 能画出并写出该模式的类结构(接口、继承、组合) 用 Java/Python 实现一个观察者模式
L3 权衡与变体 知道模式带来的代价(增加类数量、降低可读性)以及何时不用 观察者模式容易造成通知顺序混乱,有时用事件总线更好

所以,掌握设计模式 = 脑子里储存了足够多的、针对不同变化场景的类拓扑结构模型,并且能在合适的场景下调用、改造它们

它不神秘,它是一项非常实在的技能:知道多个类之间可以怎么连接,并且知道每种连接的代价和收益


四、再补充几个澄清,帮你避免被误导

很多人在网上看设计模式文章,容易产生误解。这里澄清三点:

  1. 设计模式不是代码库,不是复制粘贴就能用的。

    它是结构思想,需要你根据当前场景调整类名、关系、粒度。

  2. 设计模式不是只能用于"大项目"。

    小项目中过度使用会增加复杂度,但理解它在复杂场景的价值,能让你在遇到复杂需求时做出更合理的决策。

  3. 设计模式 ≠ 类图上的那些箭头。

    真正的模式包含问题、上下文、权衡、已知用途。拓扑结构只是它的骨架,不是全部。


五、一个彩蛋:设计模式与软件架构模式的关系

如果你还想再拔高一下视角,可以知道这个区别:

  • 设计模式:解决局部(几个类)的拓扑结构问题。
  • 架构模式:解决整个系统(多个模块/子系统)的组织结构,比如 MVC、微服务、分层架构。

两者是"建材"与"建筑"的关系。举个例子:一个 MVC 架构里,可能大量使用观察者模式 (视图观察模型的变化),以及策略模式(控制器选择不同的行为策略)。

理解这个关系,能帮你把设计模式放到更大的软件设计图景中。


写在最后

设计模式不是什么高不可攀的秘籍。它就是在面向对象编程发展了几十年后,人们不断踩坑、总结出来的一系列类的拓扑结构方案

  • 它是为了解决"需求总在变化,但代码不能总推倒重来"这个现实问题而生的。
  • 它的本质是若干个类通过继承、实现、组合三种关系连接成的特定形状。
  • 掌握它,就是掌握了一套在不同场景下如何组织类间关系的经验库。

下次当你再看到 if-else 满天飞,或者新加一个功能就要改一堆老代码时,不妨停下来想一想:

我是不是可以换一种类的拓扑结构,让代码变得更友好?

那样,你就真正开始理解设计模式了。


如果你觉得这篇文章对你有用,欢迎收藏、转发。也可以留言告诉我你想看哪个具体模式的"拓扑结构拆解",我会继续写。

相关推荐
H Journey1 小时前
Linux VIM介绍与常用命令
linux·运维·vim
铁皮哥1 小时前
【agent 开发】Claude Code 的 Skill 是怎么被加载的?从 name/description 到 SKILL.md 再到资源文件
java·服务器·数据库·python·gitee·github·软件工程
bukeyiwanshui1 小时前
20260526 综合实践:企业网站上云部署实践
运维·服务器
Arik~朽木2 小时前
Ubuntu 安装指南
linux·运维·ubuntu
難釋懷2 小时前
Nginx高可用配置
linux·nginx·php
IMPYLH2 小时前
Linux 的 yes 命令
linux·运维·服务器·数据库·bash
土星云SaturnCloud2 小时前
土星云AI边缘计算的算法应用-人脸检测
服务器·人工智能·ai·边缘计算
东城绝神2 小时前
《Linux运维实战:使用脚本模拟服务器CPU内存磁盘使用率》
linux·运维·服务器
染翰2 小时前
Linux root用户安装配置Git
linux·git·后端