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. 持续优化:代码重构时考虑设计模式的合理引入
相关推荐
我命由我1234510 小时前
Vue3 开发中,字符串中的 <br\> 标签被直接当作文本显示出来了,而不是被解析为 HTML 换行标签
开发语言·前端·javascript·vue.js·html·ecmascript·html5
运维行者_10 小时前
MSP网络管理破局者:IPAM+SPM插件终结IP冲突与安全威胁
运维·服务器·开发语言·网络·安全·web安全·php
人间打气筒(Ada)10 小时前
「码动四季·开源同行」go语言:如何处理 Go 错误异常与并发陷阱?
开发语言·后端·golang·defer·panic·errors·并发陷阱
wjcroom10 小时前
电子python模拟出的一个完美风暴
开发语言·python·数学建模·物理学
aini_lovee10 小时前
基于多时间尺度滚动优化的多能源微网双层调度模型(MATLAB实现)
开发语言·matlab·能源
极创信息10 小时前
不同开发语言程序如何做信创适配认证?完整流程与评价指标有哪些
java·c语言·开发语言·python·php·ruby·hibernate
女王大人万岁10 小时前
Golang实战gin-swagger:自动生成API文档
服务器·开发语言·后端·golang·gin
Seven9710 小时前
用300行代码手写SpringBoot核心原理
java
wregjru10 小时前
【MySQL】5. 数据更新与查询详解
java·数据库·mysql
洛阳吕工10 小时前
【Python 教程】无人机 MAVLink 通信完整实战:连接飞控、接收数据与发送指令
开发语言·python·无人机