Java常用设计模式

引言

设计模式是软件工程中的经典概念,是前人总结的代码设计经验精华。在Java企业级开发中,合理运用设计模式能够显著提升代码的可维护性、可扩展性和复用性。本文将详细介绍Java开发中最常用的六种设计模式,结合实际应用场景,帮助开发者快速掌握核心设计模式的使用技巧。


一、单例模式(Singleton)

模式概述

单例模式确保一个类只有一个实例,并提供全局访问点。这是Java中最简单却最实用的设计模式之一。

核心特点

  • 唯一实例:JVM保证类只有一个实例
  • 全局访问:提供静态方法获取唯一实例
  • 延迟加载:支持懒加载以节省资源

典型应用场景

  • ✓ 无状态工具类(日期转换、加密工具)
  • ✓ 配置管理类(全局配置参数)
  • ✓ 数据库连接池(资源复用)
  • ✓ Spring Bean(默认单例管理)

代码示例

bash 复制代码
public class Singleton {
    private static volatile Singleton instance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

二、工厂模式(Factory)

模式概述

工厂模式封装对象创建逻辑,将创建过程与使用过程解耦,符合"依赖倒置原则",避免直接new对象。

三种类型

  • 简单工厂:一个工厂生产多种产品
  • 工厂方法:每种产品对应一个工厂方法
  • 抽象工厂:生产一系列相关产品的完整家族

典型应用场景

  • Spring BeanFactory:创建Spring Bean
  • MyBatis SqlSessionFactory:创建数据库会话
  • 支付网关:微信支付、支付宝、银联统一入口

三、代理模式(Proxy)

模式概述

代理模式通过代理对象控制对原对象的访问,在不改变原类的情况下实现功能增强。

两种实现方式

|---------|--------|-----------|
| 方式 | 适用场景 | 原理 |
| JDK动态代理 | 实现接口的类 | 运行时生成代理类 |
| CGLIB | 无接口类 | 继承方式字节码增强 |

典型应用场景

  • ✓ Spring AOP(面向切面编程)
  • ✓ 事务管理(自动提交/回滚)
  • ✓ 权限校验(访问控制)
  • ✓ 远程服务调用(RMI、WebService)
  • ✓ 延迟加载(懒加载图片/数据)

四、策略模式(Strategy)

模式概述

策略模式定义算法家族,将每个算法封装成独立类,使它们可以相互替换,避免大量if-else分支。

典型应用场景

  • 电商优惠系统:满减、折扣、优惠券、N倍积分
  • 物流计费:不同物流渠道、不同重量段、不同地区
  • 会员等级折扣:普通会员、银卡会员、金卡会员、钻石会员

代码示例

bash 复制代码
// 策略接口
interface DiscountStrategy {
    double calculate(double price);
}

// 具体策略
class FullMinusStrategy implements DiscountStrategy {
    public double calculate(double price) {
        return price >= 200 ? price - 30 : price;
    }
}

五、模板方法模式(Template Method)

模式概述

模板方法模式定义算法骨架,将可变步骤延迟到子类实现,解决"通用流程个性化"问题。

核心思想

  • 不变部分:在父类中统一实现
  • 可变部分:留给子类重写实现

典型应用场景

  • ✓ 业务流程标准化(订单处理流程)
  • ✓ 框架设计(Spring JdbcTemplate)
  • ✓ 数据处理流程(获取→处理→保存)

六、装饰器模式(Decorator)

模式概述

装饰器模式动态给对象添加额外功能,不改变原有类结构,比继承更灵活。

对比继承

|-------|---------|
| 继承方式 | 装饰器方式 |
| 编译时确定 | 运行时动态添加 |
| 类爆炸问题 | 灵活组合 |
| 破坏封装 | 保持封装 |

经典案例:Java IO流

  • FileReader (被装饰者)
  • BufferedReader (添加缓冲功能)
  • LineNumberReader (添加行号功能)

总结与建议

核心模式速查表

|----|--------|-----|
| 模式 | 作用 | 难度 |
| 单例 | 确保唯一实例 | ⭐ |
| 工厂 | 解耦对象创建 | ⭐⭐ |
| 代理 | 控制对象访问 | ⭐⭐ |
| 策略 | 动态选择算法 | ⭐⭐ |
| 模板 | 定义流程骨架 | ⭐⭐ |
| 装饰 | 动态添加功能 | ⭐⭐⭐ |

实践建议

  1. 避免过度设计:不是所有场景都需要设计模式
  2. 理解本质:掌握模式背后的设计思想,而非机械套用
  3. 结合框架:Spring中蕴含大量设计模式,学习源码提升理解
  4. 持续优化:代码重构时考虑设计模式的合理引入
相关推荐
秋916 分钟前
OceanBase与GreatSQL在Java应用中的性能调优方法有哪些?
java·开发语言·oceanbase
澈20718 分钟前
C++多态编程:从原理到实战
开发语言·c++
今天又在写代码26 分钟前
并发问题解决
java·开发语言·数据库
聆风吟º27 分钟前
【C标准库】深入理解C语言strcat函数:字符串拼接的利器
c语言·开发语言·strcat·库函数
带娃的IT创业者31 分钟前
深度解析:从零构建高性能 LLM API 中转网关与成本优化实战
开发语言·gpt·llm·php·高性能·成本优化·api网关
老王以为34 分钟前
前端视角下的 Java
java·javascript·程序员
看腻了那片水42 分钟前
开源一个对业务代码零侵入的透明数据治理框架 —— 【sangsang】
java·mybatis
TechWayfarer43 分钟前
IP归属地运营商能解决什么问题?风控/增长/数据平台落地实践(附API代码)
开发语言·网络·python·网络协议·tcp/ip
Nyarlathotep01131 小时前
JUC工具(3):StampedLock的基础和原理
java·后端