侧边栏壁纸
博主头像
SeaDream乄造梦

Dream,Don't stop a day of hard and don't give up a little hope。 ——不停止一日努力&&不放弃一点希望。

  • 累计撰写 129 篇文章
  • 累计创建 34 个标签
  • 累计收到 15 条评论

目 录CONTENT

文章目录

软件开发 23 种设计模式完全指南(增强版)- 飞书文档深度内容

SeaDream乄造梦
2026-03-22 / 0 评论 / 0 点赞 / 9 阅读 / 7,250 字
温馨提示:
亲爱的,如果觉得博主很有趣就留下你的足迹,并收藏下链接在走叭

软件开发 23 种设计模式完全指南(增强版)

写在前面:这是全网最详细的设计模式教程之一。每个模式都包含:定义、核心思想、使用场景、优缺点、完整代码示例(Go 语言)、实战案例、模式对比。建议收藏慢慢读。


📚 目录

  1. 设计模式概述
  2. 创建型模式(5 种)
  3. 结构型模式(7 种)
  4. 行为型模式(11 种)
  5. 设计模式选择指南
  6. 实战建议

🎯 设计模式概述

什么是设计模式?

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

核心价值

  • ✅ 可复用:解决常见问题,避免重复造轮子
  • ✅ 易理解:标准化命名,降低沟通成本
  • ✅ 可维护:提高代码可读性和可扩展性

设计模式的六大原则

原则英文说明
单一职责SRP一个类只负责一项职责
开闭原则OCP对扩展开放,对修改关闭
里氏替换LSP子类可以替换父类
依赖倒置DIP依赖抽象,不依赖具体实现
接口隔离ISP使用多个专门的接口
迪米特法则LoD最少知道原则

设计模式的分类

23 种设计模式分为三大类:

  1. 创建型模式(5 种):对象的创建机制
  2. 结构型模式(7 种):类和对象的组合方式
  3. 行为型模式(11 种):对象之间的职责分配

🔨 创建型模式(5 种)

关注对象的创建过程,将对象的创建和使用分离。

1. 单例模式(Singleton)

📖 定义

确保一个类只有一个实例,并提供一个全局访问点。

🎯 使用场景

  • 数据库连接池
  • 日志记录器
  • 配置管理器
  • 线程池
  • 缓存系统

✅ 优点

  • 内存中只有一个实例,减少内存开销
  • 全局访问点,方便使用
  • 避免对资源的多重占用

❌ 缺点

  • 扩展困难(违背开闭原则)
  • 多线程环境需要同步处理
  • 测试困难(全局状态难以重置)

💻 Go 代码示例

package singleton

import (
    "fmt"
    "sync"
)

type Singleton struct {
    name string
    data map[string]interface{}
}

var instance *Singleton
var once sync.Once

func GetInstance() *Singleton {
    once.Do(func() {
        instance = &Singleton{
            name: "default",
            data: make(map[string]interface{}),
        }
    })
    return instance
}

func (s *Singleton) Set(key string, value interface{}) {
    s.data[key] = value
}

func (s *Singleton) Get(key string) interface{} {
    return s.data[key]
}

🔧 实战案例:数据库连接管理器

type DBManager struct {
    db *sql.DB
    mu sync.Mutex
}

var dbInstance *DBManager
var dbOnce sync.Once

func GetDBManager() *DBManager {
    dbOnce.Do(func() {
        db, err := sql.Open("mysql", "user:pass@tcp(localhost:3306)/dbname")
        if err != nil {
            panic(err)
        }
        db.SetMaxOpenConns(100)
        db.SetMaxIdleConns(10)
        dbInstance = &DBManager{db: db}
    })
    return dbInstance
}

2. 工厂方法模式(Factory Method)

📖 定义

定义一个创建对象的接口,让子类决定实例化哪个类。

🎯 使用场景

  • 系统需要灵活扩展新产品
  • 调用者不需要知道具体产品类
  • 创建对象需要复杂逻辑

✅ 优点

  • 符合开闭原则
  • 符合单一职责
  • 符合依赖倒置

❌ 缺点

  • 每增加一个产品就要增加一个工厂类
  • 增加系统复杂度

💻 Go 代码示例

type Product interface {
    Use()
    Name() string
}

type ConcreteProductA struct{}

func (p *ConcreteProductA) Use() {
    fmt.Println("使用产品 A")
}

func (p *ConcreteProductA) Name() string {
    return "ProductA"
}

type Factory interface {
    CreateProduct() Product
}

type ConcreteFactoryA struct{}

func (f *ConcreteFactoryA) CreateProduct() Product {
    return &ConcreteProductA{}
}

3. 抽象工厂模式(Abstract Factory)

📖 定义

提供一个创建一系列相关或相互依赖对象的接口,无需指定具体类。

🎯 使用场景

  • 系统需要独立于产品的创建
  • 系统要由多个产品系列中的一个来配置
  • 产品族中的产品相互依赖

✅ 优点

  • 隔离具体类的实现
  • 易于交换产品系列
  • 有利于产品的一致性

❌ 缺点

  • 增加新的产品等级结构困难
  • 抽象工厂接口修改影响大

💻 Go 代码示例

type Button interface {
    Paint()
}

type Border interface {
    Draw()
}

type MacButton struct{}

func (b *MacButton) Paint() {
    fmt.Println("绘制 Mac 风格按钮")
}

type GUIFactory interface {
    CreateButton() Button
    CreateBorder() Border
}

type MacFactory struct{}

func (f *MacFactory) CreateButton() Button {
    return &MacButton{}
}

func (f *MacFactory) CreateBorder() Border {
    return &MacBorder{}
}

4. 建造者模式(Builder)

📖 定义

将一个复杂对象的构建与它的表示分离,同样的构建过程可以创建不同的表示。

🎯 使用场景

  • 创建复杂对象
  • 创建算法独立于组成部分
  • 需要精细控制创建过程

✅ 优点

  • 封装复杂对象的创建逻辑
  • 可以控制创建过程
  • 符合开闭原则

❌ 缺点

  • 产品必须有共同点
  • 增加 Builder 类

💻 Go 代码示例

type Computer struct {
    CPU     string
    Memory  string
    Storage string
    GPU     string
}

type ComputerBuilder interface {
    SetCPU(cpu string)
    SetMemory(memory string)
    SetStorage(storage string)
    SetGPU(gpu string)
    GetComputer() *Computer
}

type ConcreteComputerBuilder struct {
    computer *Computer
}

func (b *ConcreteComputerBuilder) SetCPU(cpu string) {
    b.computer.CPU = cpu
}

func (b *ConcreteComputerBuilder) GetComputer() *Computer {
    return b.computer
}

type Director struct {
    builder ComputerBuilder
}

func (d *Director) BuildGamingPC() *Computer {
    d.builder.SetCPU("Intel i9-13900K")
    d.builder.SetMemory("32GB DDR5")
    d.builder.SetGPU("NVIDIA RTX 4090")
    return d.builder.GetComputer()
}

5. 原型模式(Prototype)

📖 定义

通过复制现有对象来创建新对象,而不是通过 new 操作符。

🎯 使用场景

  • 创建成本较高
  • 需要多个相似对象
  • 对象的创建依赖运行时状态

✅ 优点

  • 性能优于直接实例化
  • 简化创建过程
  • 可以动态增加或减少产品类

❌ 缺点

  • 需要实现克隆方法
  • 深克隆实现复杂

💻 Go 代码示例

type Prototype interface {
    Clone() Prototype
}

type User struct {
    Name     string
    Age      int
    Settings map[string]interface{}
}

func (u *User) Clone() Prototype {
    data, _ := json.Marshal(u)
    clone := &User{}
    json.Unmarshal(data, clone)
    return clone
}

type PrototypeRegistry struct {
    prototypes map[string]Prototype
}

func (r *PrototypeRegistry) Clone(name string) Prototype {
    if p, ok := r.prototypes[name]; ok {
        return p.Clone()
    }
    return nil
}

🔷 结构型模式(7 种)

关注类和对象的组合方式,形成更大的结构。

6. 适配器模式(Adapter)

📖 定义

将一个类的接口转换成客户希望的另一个接口,使原本不兼容的类可以一起工作。

🎯 使用场景

  • 使用已有类但接口不兼容
  • 统一多个类的接口
  • 第三方库集成

✅ 优点

  • 提高代码复用性
  • 符合开闭原则
  • 增加类的透明度

❌ 缺点

  • 过多使用会增加系统复杂度
  • 增加代码阅读难度

💻 Go 代码示例

type OldPrinter struct {
    brand string
}

func (o *OldPrinter) PrintFile(fileName string) {
    fmt.Printf("[旧打印机 %s] 打印文件:%s\n", o.brand, fileName)
}

type NewPrinter interface {
    Print(fileName string)
    ConnectNetwork(ip string)
}

type PrinterAdapter struct {
    oldPrinter *OldPrinter
}

func (a *PrinterAdapter) Print(fileName string) {
    a.oldPrinter.PrintFile(fileName)
}

func (a *PrinterAdapter) ConnectNetwork(ip string) {
    fmt.Printf("[适配器] 网络转换:%s\n", ip)
}

7. 桥接模式(Bridge)

📖 定义

将抽象部分与它的实现部分分离,使它们可以独立地变化。

🎯 使用场景

  • 不希望在抽象和实现之间有永久绑定
  • 抽象和实现都需要扩展
  • 类爆炸问题

✅ 优点

  • 分离抽象和实现
  • 提高系统可扩展性
  • 符合开闭原则

❌ 缺点

  • 增加系统复杂度
  • 需要正确识别两个独立变化的维度

8. 组合模式(Composite)

📖 定义

将对象组合成树形结构以表示"部分 - 整体"的层次结构。

🎯 使用场景

  • 树形结构的数据
  • 需要统一处理单个和组合对象
  • 部分 - 整体层次结构

✅ 优点

  • 简化客户端代码
  • 易于增加新组件
  • 天然支持递归

❌ 缺点

  • 设计较复杂
  • 不易限制组件类型

9. 装饰器模式(Decorator)

📖 定义

动态地给一个对象增加一些额外的职责,比生成子类更为灵活。

🎯 使用场景

  • 需要动态增加职责
  • 职责可以撤销
  • 组合爆炸问题

✅ 优点

  • 灵活性高,动态组合
  • 符合开闭原则
  • 可以叠加多个装饰器

❌ 缺点

  • 增加系统复杂度
  • 调试困难(多层嵌套)

10. 外观模式(Facade)

📖 定义

为子系统中的一组接口提供一个统一的接口,使得子系统更容易使用。

🎯 使用场景

  • 复杂子系统需要简单接口
  • 降低耦合
  • 定义层次结构的入口点

✅ 优点

  • 简化使用
  • 降低耦合
  • 符合迪米特法则

❌ 缺点

  • 限制灵活性
  • 外观类可能变成上帝类

11. 享元模式(Flyweight)

📖 定义

通过共享技术有效地支持大量细粒度的对象。

🎯 使用场景

  • 大量相似对象占用大量内存
  • 对象状态可分离
  • 不依赖对象身份

✅ 优点

  • 减少内存占用
  • 提高性能
  • 集中管理共享状态

❌ 缺点

  • 增加系统复杂度
  • 需要分离内外部状态

12. 代理模式(Proxy)

📖 定义

为其他对象提供一种代理以控制对这个对象的访问。

🎯 使用场景

  • 远程代理
  • 虚拟代理(延迟加载)
  • 保护代理
  • 缓存代理

✅ 优点

  • 协调调用者和被调用者
  • 降低系统耦合度
  • 扩展功能灵活

❌ 缺点

  • 增加系统复杂度
  • 可能增加请求处理时间

🎭 行为型模式(11 种)

关注对象之间的通信和职责分配。

13. 策略模式(Strategy)

📖 定义

定义一系列可互换的算法,使它们可以相互替换。

🎯 使用场景

  • 多个算法可互换
  • 避免大量 if-else
  • 算法独立于使用它的客户端

✅ 优点

  • 避免多重条件判断
  • 符合开闭原则
  • 算法可以自由切换

❌ 缺点

  • 客户端必须了解所有策略
  • 增加策略类数量

14. 模板方法模式(Template Method)

📖 定义

定义一个操作中的算法骨架,将某些步骤延迟到子类中。

🎯 使用场景

  • 一次性实现算法不变部分
  • 将可变行为留给子类
  • 代码复用

✅ 优点

  • 封装不变部分,扩展可变部分
  • 提取公共代码
  • 符合开闭原则

❌ 缺点

  • 每个实现都需要一个子类
  • 导致类数量增加

15. 观察者模式(Observer)

📖 定义

定义对象间的一对多依赖,当一个对象状态改变时,所有依赖者都收到通知。

🎯 使用场景

  • 一个对象变化需要通知多个对象
  • 对象间需要解耦
  • 事件驱动系统

✅ 优点

  • 目标与观察者解耦
  • 支持广播通信
  • 符合开闭原则

❌ 缺点

  • 循环依赖可能导致系统崩溃
  • 观察者过多时性能问题

16. 迭代器模式(Iterator)

📖 定义

提供一种方法顺序访问聚合对象中的各个元素,而不暴露其内部表示。

🎯 使用场景

  • 访问聚合对象内容
  • 支持多种遍历方式
  • 统一遍历接口

✅ 优点

  • 支持多种遍历方式
  • 简化聚合类
  • 同一接口遍历不同聚合

❌ 缺点

  • 增加系统复杂度
  • 抽象性增加

17. 责任链模式(Chain of Responsibility)

📖 定义

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。

🎯 使用场景

  • 多个对象可以处理同一请求
  • 不确定哪个对象处理
  • 动态指定处理者

✅ 优点

  • 降低耦合
  • 简化对象连接
  • 增强灵活性

❌ 缺点

  • 可能没有处理者
  • 性能影响(长链)
  • 调试困难

18. 命令模式(Command)

📖 定义

将请求封装为对象,使你可以参数化客户端、队列或日志请求。

🎯 使用场景

  • 需要支持撤销/重做
  • 需要记录请求日志
  • 需要支持事务

✅ 优点

  • 降低耦合
  • 支持撤销/重做
  • 支持组合命令

❌ 缺点

  • 增加系统复杂度
  • 导致过多命令类

19. 备忘录模式(Memento)

📖 定义

在不破坏封装性的前提下,捕获和外部化一个对象的内部状态,以便以后恢复。

🎯 使用场景

  • 需要保存对象状态
  • 支持撤销操作
  • 状态历史管理

✅ 优点

  • 提供状态恢复机制
  • 保持封装边界

❌ 缺点

  • 消耗资源(存储状态)
  • 可能导致高成本

20. 状态模式(State)

📖 定义

允许一个对象在其内部状态改变时改变它的行为。

🎯 使用场景

  • 对象行为依赖状态
  • 状态转换逻辑复杂
  • 避免大量条件判断

✅ 优点

  • 封装状态转换规则
  • 消除条件分支
  • 符合开闭原则

❌ 缺点

  • 增加类和对象数量
  • 结构复杂

21. 中介者模式(Mediator)

📖 定义

用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用。

🎯 使用场景

  • 对象间存在复杂通信
  • 需要减少循环依赖
  • 需要复用对象

✅ 优点

  • 减少类间耦合
  • 简化协议
  • 集中控制

❌ 缺点

  • 中介者可能变成上帝类
  • 系统复杂度增加

22. 访问者模式(Visitor)

📖 定义

表示一个作用于某对象结构中的各元素的操作,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

🎯 使用场景

  • 对象结构稳定
  • 需要定义新操作
  • 算法与对象结构分离

✅ 优点

  • 增加新操作容易
  • 收集相关操作
  • 跨越继承层次

❌ 缺点

  • 增加新元素困难
  • 破坏封装

23. 解释器模式(Interpreter)

📖 定义

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

🎯 使用场景

  • 需要解释执行语言
  • 简单语法解析
  • 脚本引擎

✅ 优点

  • 易于改变和扩展文法
  • 实现文法简单

❌ 缺点

  • 复杂文法难以维护
  • 性能问题

📊 设计模式选择指南

问题推荐模式
创建一个对象工厂方法、抽象工厂、建造者
确保只有一个实例单例
对象创建成本高原型
接口不兼容适配器
需要简单接口外观
动态增加职责装饰器
树形结构组合
大量相似对象享元
控制访问代理
算法可互换策略
算法骨架固定模板方法
一对多依赖观察者
顺序访问迭代器
多个处理者责任链
支持撤销/重做命令、备忘录
状态决定行为状态
减少对象间耦合中介者
增加新操作访问者
解释语言解释器

💡 实战建议

1. 不要过度设计

"设计模式是为了让代码更好,而不是为了用模式而用模式。"

原则

  • ✅ 先写简单代码,重构时再引入模式
  • ✅ 模式是手段,不是目的
  • ✅ KISS 原则(Keep It Simple, Stupid)

2. 识别"代码坏味道"

需要引入模式的信号:

  • ❌ 大量 if-else 或 switch
  • ❌ 重复的创建逻辑
  • ❌ 紧耦合的类
  • ❌ 难以扩展的代码

3. 经典组合

  • 工厂 + 模板方法:框架设计
  • 策略 + 工厂:动态选择算法
  • 观察者 + 中介者:事件系统
  • 装饰器 + 策略:动态增强

📚 学习资源

书籍推荐

  • 《设计模式:可复用面向对象软件的基础》(GoF)
  • 《Head First 设计模式》
  • 《重构与模式》

在线资源

  • Refactoring.Guru(图解设计模式)
  • SourceMaking(设计模式教程)

🎯 总结

设计模式的核心价值:

  • ✅ 提高代码质量:可读、可维护、可扩展
  • ✅ 降低沟通成本:标准化命名
  • ✅ 避免重复造轮子:复用成熟方案
  • ✅ 提升设计能力:站在巨人肩膀上

学习建议

  • ✅ 理解思想,而非死记代码
  • ✅ 在实战中应用
  • ✅ 理解适用场景,避免滥用

"设计模式不是银弹,但掌握它们能让你写出更好的代码。"


关于作者:糯米,正在爱 AI 协作者。每天分享技术干货和深度思考。关注我,一起成长。

原文链接https://feishu.cn/docx/RaliddWXsocibDxO3ECcy9qmn3d

标签:#设计模式 #Go 语言 #软件工程 #代码质量 #编程思维 #技术成长

0

评论区