news 2026/8/21 11:15:21

Java设计模式:从入门到精通

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java设计模式:从入门到精通

1. 引言

设计模式是软件开发中解决特定问题的经典、可复用的解决方案模板。它们不是可以直接转换为代码的完整设计,而是描述了在特定上下文中解决常见设计问题的通用方法。掌握设计模式能够帮助开发者编写出更加灵活、可维护、可扩展的代码。

在Java生态中,设计模式被广泛应用于各种框架、库和企业级应用中,例如Spring框架就大量使用了工厂模式、代理模式、模板方法模式等。理解这些模式是成为高级Java开发者的必经之路。

2. 设计模式的分类

设计模式通常分为三大类,共计23种经典模式(根据《设计模式:可复用面向对象软件的基础》一书)。

2.1 创建型模式 (Creational Patterns)

这类模式关注对象的创建机制,旨在以更灵活、更合适的方式创建对象,而不是直接使用new运算符。

  • 单例模式 (Singleton):确保一个类只有一个实例,并提供全局访问点。
  • 工厂方法模式 (Factory Method):定义一个创建对象的接口,但让子类决定实例化哪个类。
  • 抽象工厂模式 (Abstract Factory):提供一个创建一系列相关或依赖对象的接口,而无需指定它们的具体类。
  • 建造者模式 (Builder):将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
  • 原型模式 (Prototype):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

2.2 结构型模式 (Structural Patterns)

这类模式关注类和对象的组合,形成更大的结构,同时保持结构的灵活和高效。

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

2.3 行为型模式 (Behavioral Patterns)

这类模式关注对象之间的职责分配和通信。

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

3. 为什么学习设计模式?

  1. 提升代码质量:设计模式是经过时间考验的最佳实践,使用它们可以避免常见的设计缺陷,写出更健壮、更清晰的代码。
  2. 提高沟通效率:模式提供了通用的词汇表。当你说“这里用个观察者模式”,团队成员立刻就能理解你的设计意图。
  3. 增强可维护性:模式化的代码结构清晰,职责分离,使得修改和扩展变得更加容易。
  4. 加速开发过程:对于常见问题,无需从头设计,可以直接套用成熟的模式解决方案。

4. 一个简单示例:单例模式

让我们通过最常用的单例模式来感受一下设计模式在Java中的实现。

publicclassSingleton{// 1. 私有静态变量,持有唯一实例privatestaticSingletoninstance;// 2. 私有构造函数,防止外部通过new创建实例privateSingleton(){// 初始化代码}// 3. 公共静态方法,提供全局访问点publicstaticSingletongetInstance(){if(instance==null){instance=newSingleton();}returninstance;}// 示例方法publicvoiddoSomething(){System.out.println("Singleton is doing something.");}}// 使用方式publicclassMain{publicstaticvoidmain(String[]args){Singletons1=Singleton.getInstance();Singletons2=Singleton.getInstance();System.out.println(s1==s2);// 输出: true,证明是同一个对象s1.doSomething();}}

注意:上面的实现是“懒汉式”的简单版本,在多线程环境下并不安全。在实际生产中,通常会使用双重检查锁定(Double-Checked Locking)或静态内部类等方式来实现线程安全的单例。

下面提供两种线程安全的单例模式实现:

双重检查锁定(Double-Checked Locking)实现

publicclassThreadSafeSingletonDCL{// 使用 volatile 关键字确保多线程环境下的可见性和有序性privatestaticvolatileThreadSafeSingletonDCLinstance;privateThreadSafeSingletonDCL(){// 私有构造函数}publicstaticThreadSafeSingletonDCLgetInstance(){if(instance==null){// 第一次检查,避免不必要的同步synchronized(ThreadSafeSingletonDCL.class){if(instance==null){// 第二次检查,确保只创建一个实例instance=newThreadSafeSingletonDCL();}}}returninstance;}publicvoiddoSomething(){System.out.println("Thread-safe singleton (DCL) is doing something.");}}

静态内部类(Static Inner Class)实现

publicclassThreadSafeSingletonInnerClass{privateThreadSafeSingletonInnerClass(){// 私有构造函数}// 静态内部类在首次被引用时才会加载,实现了懒加载privatestaticclassSingletonHolder{privatestaticfinalThreadSafeSingletonInnerClassINSTANCE=newThreadSafeSingletonInnerClass();}publicstaticThreadSafeSingletonInnerClassgetInstance(){returnSingletonHolder.INSTANCE;// 由JVM保证线程安全}publicvoiddoSomething(){System.out.println("Thread-safe singleton (Inner Class) is doing something.");}}

两种实现的对比与使用建议

  • 双重检查锁定:性能较好,只有在第一次创建实例时需要同步。需要注意volatile关键字的使用(Java 5+),以防止指令重排序问题。
  • 静态内部类:实现更简洁,由JVM的类加载机制保证线程安全,且天然支持懒加载。是《Effective Java》推荐的方式之一。

在实际项目中,如果不需要懒加载,也可以使用**枚举(Enum)**方式实现单例,这是最简洁、安全的实现(由JVM保证实例唯一性且防反射攻击)。

publicenumEnumSingleton{INSTANCE;publicvoiddoSomething(){System.out.println("Enum singleton is doing something.");}}

5. 如何学习和应用设计模式?

  1. 理解意图:不要死记硬背类图。首先要理解这个模式解决什么问题,在什么场景下使用。
  2. 识别场景:在阅读源码或设计自己的模块时,主动思考“这里是不是可以用某个模式来优化?”
  3. 避免滥用:设计模式是工具,不是银弹。强行套用模式可能会导致过度设计,使简单问题复杂化。KISS原则(Keep It Simple, Stupid)依然重要。
  4. 结合实践:通过阅读优秀开源框架(如Spring, MyBatis, Netty)的源码,可以看到设计模式在真实项目中的精妙应用。

6. 总结

Java设计模式是构建高质量软件的重要基石。从23种经典模式入手,理解其分类、意图和适用场景,并在项目中谨慎而恰当地应用,将极大地提升你的设计能力和代码水平。学习之路可以从创建型模式开始,再到结构型,最后深入行为型模式,循序渐进,并结合实际项目进行练习。

记住,模式的核心思想比具体的实现方式更重要。最终目标是写出易读、易维护、易扩展的代码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 11:13:52

从原理到实战:基于Real-ESRGAN与RIFE的动画视频4K超分补帧全流程

在实际的视频处理项目中,我们常常会遇到一些经典动画片段或影视素材,它们可能因为年代久远或原始分辨率限制,无法满足当下高清、高流畅度的播放需求。例如,许多动画爱好者希望将《地缚少年花子君》中的经典名场面进行高清化处理&a…

作者头像 李华
网站建设 2026/8/21 11:09:51

FNF Mod开发进阶:QT rewired输入系统与SKY QT扩展整合全攻略

最近在折腾《Friday Night Funkin》(FNF) 的 Mod 开发时,发现社区里关于 QT rewired 和 SKY QT 扩展 的讨论热度很高,尤其是配合“2倍速60帧”这类性能优化需求时,很多开发者对如何整合这些工具、它们到底更新了什么、以及如何实现全流程…

作者头像 李华
网站建设 2026/8/21 11:09:32

华为OD机试双机位C卷人力分配题目解析与实现

1. 华为OD机试双机位C卷人力分配题目解析 最近在准备华为OD机试的同学们应该都注意到了这个新出现的题型——双机位C卷中的部门人力分配问题。作为一道出现在华为OD机试中的编程题,它考察的不仅是基础的编程能力,更注重解决实际业务场景中的资源分配问题…

作者头像 李华
网站建设 2026/8/21 11:08:54

防火墙规则配置:允许与拒绝规则的设置方法,实操教程

防火墙规则配置:允许与拒绝规则的设置方法,实操教程📝 本章学习目标:本章介绍网络服务,帮助读者掌握常见网络服务的配置与管理。通过本章学习,你将全面掌握"防火墙规则配置:允许与拒绝规则…

作者头像 李华
网站建设 2026/8/21 11:07:40

向量检索缓存设计的复盘记录怎样使用

向量检索缓存设计的复盘记录怎样使用 先把边界说清楚 本文讨论「Redis Vector Search 与多级缓存设计:可复制的项目复盘模板与决策记录」的设计与验证方法。文中的场景用于说明排查和决策过程,不对应某次线上事故,也不代表任何项目的性能数据…

作者头像 李华
网站建设 2026/8/21 11:06:24

构建对抗性合成网络基准:诊断与提升语言智能体认知稳健性

1. 项目概述:为什么我们需要一个“合成网络”来拷问语言智能体? 最近在折腾大语言模型应用,特别是检索增强生成(RAG)和智能体(Agent)时,我总被一个问题困扰:我们怎么知道…

作者头像 李华