欢迎光临
我们一直在努力

23种设计模式精讲:从入门到精通,一文掌握设计模式核心思想

面试中经常被问到设计模式?项目中不知道如何应用设计模式优化代码?面对复杂系统设计感到无从下手?本文全面讲解23种GoF设计模式,包括6大设计原则、5种创建型模式、7种结构型模式、11种行为型模式,结合UML类图、源码解析和实战案例,助你成为架构设计高手,轻松应对大厂面试!


📋 文章目录

  • 一、设计模式概述
    • 1.1 代码质量评价标准
    • 1.2 编程方法论
    • 1.3 设计模式分类
  • 二、UML类图
  • 三、六大设计原则(SOLID)
  • 四、创建型模式(5种)
    • 4.1 单例模式
    • 4.2 工厂方法模式
    • 4.3 抽象工厂模式
    • 4.4 建造者模式
    • 4.5 原型模式
  • 五、结构型模式(7种)
    • 5.1 代理模式
    • 5.2 桥接模式
    • 5.3 装饰者模式
    • 5.4 适配器模式
    • 5.5 门面模式
    • 5.6 组合模式
    • 5.7 享元模式
  • 六、行为型模式(11种)
  • 七、设计模式速查表

一、设计模式概述

1.1 代码质量评价标准

设计模式的目标:提高代码质量,写出可维护、可扩展、可读性强的高质量代码。

评价标准说明重要性
可维护性 不破坏原有设计、不引入新Bug的前提下快速修改代码 ⭐⭐⭐⭐⭐
可读性 代码易于理解和审查(Code Review) ⭐⭐⭐⭐⭐
可扩展性 对修改关闭,对扩展开放 ⭐⭐⭐⭐⭐
灵活性 代码能够灵活接纳新功能 ⭐⭐⭐⭐
简洁性 遵循KISS原则,简单优雅 ⭐⭐⭐⭐
可复用性 减少重复代码,DRY原则 ⭐⭐⭐⭐
可测试性 易于编写单元测试 ⭐⭐⭐⭐

1.2 编程方法论

提升代码质量的完整体系:

面向对象设计(基础)

设计原则(指导思想)

设计模式(原则的具体实现)

编程规范(提高可读性)

重构技巧(持续优化)

六大设计原则(SOLID):

原则英文缩写核心思想
单一职责原则 SRP 一个类只负责一个职责
开闭原则 OCP 对扩展开放,对修改关闭
里氏替换原则 LSP 子类可以替换父类
接口隔离原则 ISP 接口要小而专
依赖倒置原则 DIP 依赖抽象而非具体实现
迪米特法则 LoD 最少知识原则

1.3 设计模式分类

GoF(Gang of Four)23种设计模式分为三大类:

类型数量常用模式
创建型模式 5种 单例、工厂方法、抽象工厂、建造者
结构型模式 7种 代理、装饰者、适配器、桥接
行为型模式 11种 观察者、策略、模板、职责链

二、UML类图

2.1 类图表示法

符号含义Java对应
+ public 公共访问
private 私有访问
# protected 受保护访问

2.2 类之间的关系

关系图示代码示例耦合度
实现 虚线+空心三角 implements
泛化(继承) 实线+空心三角 extends
关联 实线+箭头 成员变量
聚合 实线+空心菱形 构造器传入
组合 实线+实心菱形 内部创建
依赖 虚线+箭头 方法参数

编程建议:多用组合,少用继承


三、六大设计原则(SOLID)

3.1 单一职责原则(SRP)

定义:一个类或模块只负责完成一个职责。

核心思想:不要设计大而全的类,要设计粒度小、功能单一的类。

判断标准:

  • 类中的代码行数、函数过多
  • 类依赖的其他类过多
  • 私有方法过多
  • 大量方法集中操作几个属性

3.2 开闭原则(OCP)⭐最重要

定义:对扩展开放,对修改关闭。

实现方式:

  • 通过接口或抽象类定义稳定的行为
  • 通过具体实现类来扩展功能
  • 示例:

    // 抽象接口 – 稳定
    public interface IStrategy {
    double realPrice(double consumePrice);
    }

    // 具体实现 – 可扩展
    public class PromotionalStrategy implements IStrategy {
    public double realPrice(double consumePrice) {
    if (consumePrice > 200) {
    return 200 + (consumePrice 200) * 0.8;
    }
    return consumePrice;
    }
    }

    public class RebateStrategy implements IStrategy {
    public double realPrice(double consumePrice) {
    return consumePrice * 0.8;
    }
    }

    3.3 里氏替换原则(LSP)

    定义:子类对象能够替换程序中父类对象出现的任何地方,并且保证程序逻辑行为不变。

    核心:子类可以扩展父类功能,但不能改变父类原有功能。

    3.4 接口隔离原则(ISP)

    定义:客户端不应该被迫依赖于它不使用的方法。

    与单一职责原则的区别:

    • 单一职责原则约束的是类
    • 接口隔离原则约束的是接口

    3.5 依赖倒置原则(DIP)

    定义:

  • 高层模块不应该依赖低层模块,两者都应该依赖抽象
  • 抽象不应该依赖细节,细节应该依赖抽象
  • 实现方式:面向接口编程

    3.6 迪米特法则(LoD)

    定义:最少知识原则,talk only to your immediate friends(只和你最亲密的朋友交谈)。

    核心:降低类之间的耦合度。


    四、创建型模式(5种)

    创建型模式提供创建对象的机制,提升已有代码的灵活性和复用性。

    4.1 单例模式 ⭐⭐⭐⭐⭐

    定义:保证一个类在运行期间只有一个实例对外提供服务。

    实现方式对比:

    实现方式线程安全懒加载性能推荐度
    饿汉式 ⭐⭐⭐
    懒汉式(线程不安全)
    懒汉式(synchronized) ⭐⭐
    双重检测 ⭐⭐⭐⭐
    静态内部类 ⭐⭐⭐⭐
    枚举 ⭐⭐⭐⭐⭐

    双重检测实现:

    public class Singleton {
    // volatile保证可见性和禁止指令重排
    private volatile static Singleton instance = null;

    private Singleton() {}

    public static Singleton getInstance() {
    // 第一次检查,避免不必要的同步
    if (instance == null) {
    synchronized (Singleton.class) {
    // 第二次检查,保证线程安全
    if (instance == null) {
    instance = new Singleton();
    }
    }
    }
    return instance;
    }
    }

    枚举实现(推荐):

    public enum Singleton {
    INSTANCE;

    public void doSomething() {
    // 业务逻辑
    }
    }

    // 使用
    Singleton.INSTANCE.doSomething();

    4.2 工厂方法模式 ⭐⭐⭐⭐

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

    角色:

    • 抽象工厂(Abstract Factory)
    • 具体工厂(Concrete Factory)
    • 抽象产品(Abstract Product)
    • 具体产品(Concrete Product)

    示例:

    // 抽象产品
    public interface IFreeGoods {
    ResponseResult sendFreeGoods(AwardInfo awardInfo);
    }

    // 具体产品
    public class DiscountFreeGoods implements IFreeGoods {
    @Override
    public ResponseResult sendFreeGoods(AwardInfo awardInfo) {
    System.out.println("发放打折券");
    return new ResponseResult("200", "成功");
    }
    }

    // 抽象工厂
    public interface FreeGoodsFactory {
    IFreeGoods getInstance();
    }

    // 具体工厂
    public class DiscountFreeGoodsFactory implements FreeGoodsFactory {
    @Override
    public IFreeGoods getInstance() {
    return new DiscountFreeGoods();
    }
    }

    4.3 抽象工厂模式

    定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

    与工厂方法的区别:

    • 工厂方法:创建单一产品
    • 抽象工厂:创建产品族(一系列相关产品)

    适用场景:

    • 需要创建的产品系列有较多共性特征
    • 需要解决跨平台兼容性问题

    4.4 建造者模式 ⭐⭐⭐⭐

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

    适用场景:

    • 类的构造函数参数过多(超过4个)
    • 需要创建不可变对象

    链式调用实现:

    public class RabbitMQClient {
    private String host;
    private int port;
    private String queue;

    private RabbitMQClient(Builder builder) {
    this.host = builder.host;
    this.port = builder.port;
    this.queue = builder.queue;
    }

    public static class Builder {
    private String host = "127.0.0.1";
    private int port = 5672;
    private String queue;

    public Builder setHost(String host) {
    this.host = host;
    return this;
    }

    public Builder setPort(int port) {
    this.port = port;
    return this;
    }

    public Builder setQueue(String queue) {
    this.queue = queue;
    return this;
    }

    public RabbitMQClient build() {
    // 参数校验
    if (queue == null) {
    throw new RuntimeException("队列名称不能为空");
    }
    return new RabbitMQClient(this);
    }
    }
    }

    // 使用
    RabbitMQClient client = new RabbitMQClient.Builder()
    .setHost("192.168.1.1")
    .setPort(5672)
    .setQueue("order_queue")
    .build();

    4.5 原型模式

    定义:用已创建的实例作为原型,通过复制该原型对象来创建一个和原型相同的新对象。

    适用场景:

    • 对象创建成本大(复杂计算、IO操作)
    • 需要保存对象状态(撤销操作)

    深克隆 vs 浅克隆:

    类型基本数据类型引用类型实现方式
    浅克隆 复制值 复制引用 clone()
    深克隆 复制值 复制对象 序列化/递归clone

    深克隆实现:

    public class ConcretePrototype implements Cloneable, Serializable {
    private Person person;

    // 浅克隆
    @Override
    protected ConcretePrototype clone() throws CloneNotSupportedException {
    return (ConcretePrototype) super.clone();
    }

    // 深克隆(推荐)
    public ConcretePrototype deepClone() throws Exception {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(this);

    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return (ConcretePrototype) ois.readObject();
    }
    }


    五、结构型模式(7种)

    结构型模式总结类和对象组合在一起的经典结构。

    5.1 代理模式 ⭐⭐⭐⭐⭐

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

    三种实现方式:

    实现方式特点适用场景
    静态代理 编译时确定,需手动编写代理类 简单场景
    JDK动态代理 基于接口,运行时生成 有接口的场景
    CGLIB动态代理 基于继承,可代理普通类 无接口的场景

    JDK动态代理示例:

    public class ProxyFactory {
    private Object target;

    public ProxyFactory(Object target) {
    this.target = target;
    }

    public Object getProxyInstance() {
    return Proxy.newProxyInstance(
    target.getClass().getClassLoader(),
    target.getClass().getInterfaces(),
    (proxy, method, args) -> {
    System.out.println("前置增强");
    Object result = method.invoke(target, args);
    System.out.println("后置增强");
    return result;
    }
    );
    }
    }

    应用场景:

    • 远程代理:RPC调用
    • 虚拟代理:延迟加载
    • 保护代理:权限控制
    • 智能引用:引用计数

    5.2 桥接模式

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

    核心思想:用组合替代继承,避免类爆炸。

    示例:支付系统(支付渠道 × 支付方式)

    支付渠道(微信、支付宝)
    ↓ 组合
    支付方式(密码、人脸、指纹)

    5.3 装饰者模式

    定义:动态地给一个对象添加一些额外的职责。

    特点:

    • 比继承更灵活
    • 可以动态添加/移除功能
    • 符合开闭原则

    经典应用:Java IO流

    // 层层包装,动态添加功能
    InputStream is = new FileInputStream("test.txt");
    BufferedInputStream bis = new BufferedInputStream(is);
    DataInputStream dis = new DataInputStream(bis);

    5.4 适配器模式

    定义:将一个类的接口转换成客户希望的另外一个接口。

    两种实现:

    • 类适配器:通过继承实现
    • 对象适配器:通过组合实现(推荐)

    应用场景:

    • 接口不兼容
    • 复用旧代码
    • 统一多个类的接口

    5.5 门面模式(外观模式)

    定义:为子系统中的一组接口提供一个一致的界面。

    作用:

    • 简化客户端调用
    • 降低耦合度
    • 分层架构的入口

    5.6 组合模式

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

    适用场景:

    • 树形结构场景
    • 统一处理叶子节点和容器

    经典应用:文件系统、组织架构

    5.7 享元模式

    定义:运用共享技术有效地支持大量细粒度的对象。

    核心思想:复用对象,减少内存占用。

    经典应用:

    • Java字符串常量池
    • 数据库连接池
    • 线程池

    六、行为型模式(11种)

    行为型模式负责对象间的高效沟通和职责传递委派。

    模式定义应用场景
    观察者模式 定义对象间的一对多依赖关系 事件监听、消息订阅
    模板方法模式 定义算法骨架,子类实现步骤 框架设计、流程控制
    策略模式 定义算法族,分别封装起来 支付方式、排序算法
    职责链模式 将请求的发送者和接收者解耦 审批流程、过滤器链
    迭代器模式 提供一种方法顺序访问聚合对象 集合遍历
    状态模式 允许对象在内部状态改变时改变行为 订单状态、游戏状态
    命令模式 将请求封装为对象 撤销/重做、队列请求
    备忘录模式 在不破坏封装性的前提下捕获对象状态 撤销操作、游戏存档
    访问者模式 将数据结构与操作分离 编译器、报表生成
    中介者模式 定义一个中介对象来封装一系列对象交互 聊天室、MVC控制器
    解释器模式 为语言创建解释器 正则表达式、SQL解析

    6.1 观察者模式 ⭐⭐⭐⭐⭐

    定义:定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖于它的对象都得到通知并被自动更新。

    经典应用:

    • Java的Observable和Observer
    • Spring事件监听机制
    • 消息队列(MQ)

    6.2 模板方法模式 ⭐⭐⭐⭐

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

    经典应用:

    • Spring的JdbcTemplate
    • Servlet的doGet/doPost

    6.3 策略模式 ⭐⭐⭐⭐⭐

    定义:定义算法族,分别封装起来,让它们可以互相替换。

    经典应用:

    • Java的Comparator接口
    • Spring的Resource加载策略

    七、设计模式速查表

    7.1 设计原则速查

    原则口诀关键词
    SRP 一类一职责 粒度、内聚
    OCP 对扩展开放 抽象、接口
    LSP 子类可替换 继承、多态
    ISP 接口要分离 最小化、专注
    DIP 依赖抽象 接口编程
    LoD 最少知道 解耦、中介

    7.2 设计模式速查

    类型模式核心思想记忆口诀
    创建型 单例 全局唯一 一夫一妻
    创建型 工厂方法 子类决定实例 各司其职
    创建型 抽象工厂 创建产品族 家族企业
    创建型 建造者 分步骤构建 步步为营
    创建型 原型 复制创建 克隆自己
    结构型 代理 控制访问 找代理人
    结构型 装饰者 动态增强 锦上添花
    结构型 适配器 接口转换 转换插头
    结构型 桥接 组合代替继承 桥接两岸
    结构型 门面 统一入口 门面担当
    结构型 组合 树形结构 整体部分
    结构型 享元 共享复用 共享资源
    行为型 观察者 订阅通知 一呼百应
    行为型 策略 算法替换 随机应变
    行为型 模板方法 骨架实现 按部就班
    行为型 职责链 链式处理 层层上报

    7.3 面试高频题

  • 单例模式的线程安全实现?(双重检测、静态内部类、枚举)
  • 工厂模式与建造者模式的区别?
  • JDK动态代理与CGLIB动态代理的区别?
  • Spring中使用了哪些设计模式?
  • 浅克隆与深克隆的区别及实现?

  • 总结

    本文系统讲解了23种GoF设计模式:

  • 六大设计原则(SOLID):单一职责、开闭、里氏替换、接口隔离、依赖倒置、迪米特法则
  • 创建型模式(5种):单例、工厂方法、抽象工厂、建造者、原型
  • 结构型模式(7种):代理、桥接、装饰者、适配器、门面、组合、享元
  • 行为型模式(11种):观察者、模板方法、策略、职责链、迭代器、状态、命令、备忘录、访问者、中介者、解释器
  • 学习建议:

    • 先理解设计原则,再学习设计模式
    • 结合实际项目,在实践中应用
    • 阅读优秀框架源码(Spring、JDK)
    • 不要过度设计,简单问题简单解决

    设计模式是内功,不是招式。掌握设计思想比记忆具体实现更重要。


    关键词:设计模式, GoF, 单例模式, 工厂模式, 代理模式, 观察者模式, 策略模式, 建造者模式, SOLID原则, UML类图

    如果本文对你有帮助,欢迎点赞、收藏、关注!有任何设计模式相关问题,欢迎在评论区留言讨论。

    赞(0)
    未经允许不得转载:171主机测评 » 23种设计模式精讲:从入门到精通,一文掌握设计模式核心思想
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址