当前位置: 首页 > article >正文

深入解读五种常见 Java 设计模式及其在 Spring 框架中的应用

深入解读五种常见 Java 设计模式及其在 Spring 框架中的应用


2.1 工厂模式(Factory Pattern)

模式简介

工厂模式是创建型模式之一,它通过定义一个工厂类来负责创建对象,而不是由客户端直接实例化对象,从而实现对象创建与使用的解耦

模式结构
  • 产品接口:定义创建对象的标准接口或抽象类。
  • 具体产品类:实现产品接口,表示实际创建的对象。
  • 工厂类:封装对象的创建逻辑,对外提供方法创建不同类型的产品实例。
使用场景
  • 当对象的创建逻辑较为复杂时,通过工厂模式简化对象创建过程。
  • 当需要创建不同类型的对象,并根据参数或配置文件决定创建哪种对象时。
Java 示例代码

需求描述:一个汽车工厂可以创建不同类型的汽车(如 BMW、Audi)

// 产品接口,定义汽车的行为
public interface Car {
    void drive();  // 驾驶方法
}

// 具体产品类:宝马车
public class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("驾驶宝马汽车...");
    }
}

// 具体产品类:奥迪车
public class Audi implements Car {
    @Override
    public void drive() {
        System.out.println("驾驶奥迪汽车...");
    }
}

// 工厂类:封装创建逻辑
public class CarFactory {
    /**
     * 根据传入的类型创建汽车实例
     *
     * @param type 汽车类型(BMW或Audi)
     * @return 汽车实例
     */
    public static Car createCar(String type) {
        if ("BMW".equalsIgnoreCase(type)) {
            return new BMW();
        } else if ("Audi".equalsIgnoreCase(type)) {
            return new Audi();
        } else {
            throw new IllegalArgumentException("未知的汽车类型:" + type);
        }
    }
}

改进:加入配置化支持

如果希望可以通过配置文件修改汽车类型,可以使用 properties 文件来动态配置

Properties properties = new Properties();
properties.load(new FileInputStream("carConfig.properties"));
String carType = properties.getProperty("car.type");
Car car = CarFactory.createCar(carType);  
car.drive();
在 Spring 框架中的应用

Spring 的 IOC 容器就是工厂模式的经典实现。Spring 容器通过 ApplicationContext 提供对象实例,而不需要手动创建对象:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = context.getBean("car", Car.class);
car.drive();  // 从容器中获取 Bean 实例,而非直接 new

在 Spring 代码中,BeanFactoryFactoryBean 也是工厂模式的具体实现:

public class MyCarFactoryBean implements FactoryBean<Car> {
    @Override
    public Car getObject() {
        return new BMW();  // 工厂方法返回具体的 Car 实例
    }

    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }
}

2.2 单例模式(Singleton Pattern)

模式简介

单例模式确保一个类在整个应用程序中只有一个实例,并提供全局访问点。单例模式主要用于全局共享资源的管理。

模式结构
  • 唯一实例:类内部创建一个静态的唯一实例。
  • 私有构造方法:防止外部通过 new 关键字创建新实例。
  • 全局访问方法:通过静态方法提供全局访问点。
使用场景
  • 配置管理类。
  • 日志管理类(如 Logger 类)。
  • 数据库连接池(只需要一个连接池实例)。
Java 示例代码

需求描述:实现一个单例类,保证实例唯一。

Java 示例代码
public class Singleton {
    // 静态实例,保证全局唯一
    private static Singleton instance;

    // 私有构造方法,防止外部创建实例
    private Singleton() {
        System.out.println("创建单例实例...");
    }

    // 提供全局访问点
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();  // 第一次调用时创建实例
        }
        return instance;
    }
}
在 Spring 框架中的应用

Spring 默认的 Bean 是单例模式(scope="singleton"):

<bean id="userService" class="com.example.UserService" scope="singleton" />

2.3 代理模式(Proxy Pattern)

模式简介

代理模式为其他对象提供代理对象,以控制对目标对象的访问。代理对象可以在方法调用前后添加额外操作,例如权限检查事务控制日志记录等功能。

模式结构
  • 接口:定义目标对象需要实现的方法。
  • 真实对象:实现接口的方法,表示实际业务逻辑。
  • 代理对象:持有对真实对象的引用,添加额外操作。
使用场景
  • 事务管理:如在方法调用前开启事务,方法执行后提交事务。
  • 安全控制:如在方法调用前检查用户权限。
  • 缓存机制:如在方法调用后缓存结果,提高性能。
Java 示例代码

需求描述:通过代理类为服务类添加日志记录功能。

// 服务接口
public interface UserService {
    void createUser(String username);
}

// 真实服务类,提供创建用户功能
public class RealUserService implements UserService {
    @Override
    public void createUser(String username) {
        System.out.println("创建用户:" + username);
    }
}

// 代理类,添加日志功能
public class UserServiceProxy implements UserService {
    private final RealUserService realUserService = new RealUserService();

    @Override
    public void createUser(String username) {
        System.out.println("日志记录:开始创建用户...");
        realUserService.createUser(username);
        System.out.println("日志记录:用户创建完毕!");
    }
}
在 Spring AOP 中的应用

Spring 使用动态代理机制实现 AOP,对方法调用进行拦截。例如,使用 @Transactional 注解时,Spring 在方法执行前后添加了事务管理逻辑:

@Service
public class OrderService {
    @Transactional
    public void createOrder() {
        // 事务逻辑由代理类处理
    }
}

Spring 自动为 @Transactional 方法生成代理类,负责在方法调用前后开启和提交事务。


2.4 策略模式(Strategy Pattern)

模式简介

策略模式定义了一组可互换的算法策略,并将每个策略封装到独立类中。客户端通过上下文类在运行时选择不同的策略,从而实现算法的灵活切换。

模式结构
  • 策略接口:定义策略行为。
  • 具体策略类:实现具体算法逻辑。
  • 上下文类:持有策略对象,负责在运行时调用具体策略。
使用场景
  • 支付系统中,根据不同支付方式(如支付宝、微信、银行卡)选择不同的支付策略。
  • 文件处理系统中,根据文件类型选择不同的解析器(如 XML 解析器、JSON 解析器)。
Java 示例代码

需求描述:实现一个支付系统,支持不同的支付方式。

// 策略接口
public interface PaymentStrategy {
    void pay(int amount);
}

// 具体策略类:信用卡支付
public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("使用信用卡支付:" + amount + " 元");
    }
}

// 具体策略类:PayPal 支付
public class PayPalPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("使用 PayPal 支付:" + amount + " 元");
    }
}

// 上下文类
public class PaymentContext {
    private PaymentStrategy strategy;  // 当前使用的支付策略

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void executePayment(int amount) {
        strategy.pay(amount);  // 调用具体支付策略
    }
}
在 Spring MVC 中的应用

Spring MVC 中的 HandlerAdapter 使用策略模式来处理不同类型的请求:

public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}

不同的 HandlerAdapter 实现类支持不同类型的 Controller,例如 SimpleControllerHandlerAdapter 处理 SimpleController


2.5 模板方法模式(Template Method Pattern)

模式简介

模板方法模式定义了一个算法的骨架,将具体实现延迟到子类。它允许子类在保留算法整体结构的同时重写具体步骤。

使用场景
  • 当多个子类有相似逻辑,但部分实现细节不同。
  • 数据处理系统中,文件读取、解析和写入的步骤固定,但文件格式不同。
Java 示例代码
public abstract class DataProcessor {
    public void process() {
        readData();  // 读取数据
        processData();  // 处理数据
        writeData();  // 写入数据
    }

    protected abstract void readData();
    protected abstract void processData();
    protected abstract void writeData();
}

// CSV 数据处理类
public class CSVDataProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.out.println("读取 CSV 文件数据...");
    }

    @Override
    protected void processData() {
        System.out.println("解析 CSV 文件数据...");
    }

    @Override
    protected void writeData() {
        System.out.println("写入 CSV 文件数据...");
    }
}
在 MyBatis 中的应用

MyBatis 的 SqlSessionTemplate 是模板方法模式的典型应用,封装了 SQL 执行流程:

sqlSessionTemplate.selectOne("namespace.method", parameter);

总结

通过上述设计模式的讲解,我们可以看到:

  • 工厂模式单例模式解决了对象创建问题。
  • 代理模式策略模式提高了系统的灵活性和可扩展性。
  • 模板方法模式在固定流程的场景中非常适用。

在实际项目中,合理运用设计模式能够显著提高代码质量,让系统更加灵活高效易维护。建议开发者在学习和实践中多关注常见框架中的设计模式应用,不断优化自己的代码设计能力。


http://www.kler.cn/a/502563.html

相关文章:

  • type 属性的用途和实现方式(图标,表单,数据可视化,自定义组件)
  • Android SystemUI——服务启动流程(二)
  • WPF中如何在MVVM模式下跨线程更新UI
  • HTML5实现好看的博客网站、通用大作业网页模板源码
  • 32单片机从入门到精通之安全性与可靠性——防护措施(十八)
  • 利用Java爬虫获取淘宝商品描述item_get_descAPI接口
  • 关于在协程内使用 Uvicorn 无法正常开启 Web 服务的分析处理
  • 202409 青少年软件编程等级考试C/C++ 二级真题答案及解析(电子学会)
  • 计算机网络之---IP协议
  • 数据结构二叉树-C语言
  • Windows的Redis查看自己设置的密码并更改设置密码
  • 神经网络中的“池化”是什么意思?
  • MySQL 与 Redis 的数据一致性问题
  • Linux自定义分隔符
  • 【14】模型训练自制数据集前的一些数据处理操作
  • 基于springboot果蔬供应链信息管理平台
  • Linux 下 Vim 环境安装踩坑问题汇总及解决方法(重置版)
  • AI学习路线图-邱锡鹏-神经网络与深度学习
  • 双线性插值算法:原理、实现、优化及在图像处理和多领域中的广泛应用与发展趋势(二)
  • 【数据库】Mysql精简回顾复习
  • 【人工智能】自然语言生成的前沿探索:利用GPT-2和BERT实现自动文本生成与完形填空
  • python-leetcode-长度最小的子数组
  • C#版 软件开发6大原则与23种设计模式
  • 【理论】测试框架体系TDD、BDD、ATDD、MBT、DDT介绍
  • 2025年华为OD上机考试真题(Java)——整数对最小和
  • vulnhub靶场【IA系列】之Keyring