Java 设计模式实践:工厂模式、建造者模式、单例模式与事务回滚机制

发布于:2025-02-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

Java 设计模式实践:工厂模式、建造者模式、单例模式与事务回滚机制

1. 设计模式概述

设计模式(Design Pattern)是一种解决软件开发中常见问题的最佳实践。本案例展示了如何使用 工厂模式建造者模式单例模式事务回滚机制 来实现一个灵活、可扩展且稳定的文件存储系统。


2. 工厂模式(Factory Pattern)

工厂模式 用于创建对象,同时隐藏创建逻辑,提供一个统一的接口来获取不同类型的对象。

应用场景

在本案例中,我们有多种文件存储方式(本地存储、Minio、HDFS)。如果直接在代码中 new 不同的存储类,会导致耦合度高,难以维护。因此,我们使用 工厂模式 来创建存储对象。

代码示例

class FileStorageFactory {
    private static volatile FileStorageFactory instance;

    private FileStorageFactory() {}

    public static FileStorageFactory getInstance() {
        if (instance == null) {
            synchronized (FileStorageFactory.class) {
                if (instance == null) {
                    instance = new FileStorageFactory();
                }
            }
        }
        return instance;
    }

    public FileStorage getStorage(String type) {
        switch (type.toLowerCase()) {
            case "local":
                return new LocalFileStorage();
            case "minio":
                return new MinioFileStorage();
            case "hdfs":
                return new HdfsFileStorage();
            default:
                throw new IllegalArgumentException("未知存储类型: " + type);
        }
    }
}

优点

解耦:调用方不需要知道 new 具体对象的细节,只需通过 FileStorageFactory.getStorage("local") 获取对象。
扩展性强:未来如果新增 S3FileStorage,只需修改工厂类,而不用改动原有代码。


3. 单例模式(Singleton Pattern)

单例模式 确保一个类在内存中只有一个实例,并提供全局访问点。

应用场景

工厂模式的 FileStorageFactory 需要在整个应用中只创建 一个实例,因此采用 双重检查锁(DCL)实现单例。

代码示例

public static FileStorageFactory getInstance() {
    if (instance == null) {
        synchronized (FileStorageFactory.class) {
            if (instance == null) {
                instance = new FileStorageFactory();
            }
        }
    }
    return instance;
}

优点

节省内存:全局只存在一个实例,避免重复创建对象。
线程安全:双重检查锁机制防止多线程环境下创建多个实例。


4. 建造者模式(Builder Pattern)

建造者模式 主要用于 逐步构造复杂对象,支持 链式调用,并能在 操作失败时进行回滚

应用场景

假设你要执行多个文件操作(创建、删除、修改),如果中间某个操作失败,你希望 之前的操作可以撤销,避免数据不一致的问题。

代码示例

class FileOperationBuilder {
    private final FileStorage fileStorage;
    private final List<Runnable> rollbackActions = new ArrayList<>();

    public FileOperationBuilder(FileStorage fileStorage) {
        this.fileStorage = fileStorage;
    }

    public FileOperationBuilder createFile(String path, String content) throws IOException {
        fileStorage.createFile(path, content);
        rollbackActions.add(() -> {
            try {
                fileStorage.deleteFile(path);
                System.out.println("🔄 回滚 - 删除文件: " + path);
            } catch (IOException e) {
                System.err.println("⚠️ 回滚失败 - 删除文件: " + path);
            }
        });
        return this;
    }

    public void rollback() {
        System.out.println("⚠️ 发生错误,执行回滚...");
        for (int i = rollbackActions.size() - 1; i >= 0; i--) {
            rollbackActions.get(i).run();
        }
    }
}

优点

链式调用:代码可读性更强,调用方式更简洁。
事务回滚:如果某一步失败,可以回滚前面已执行的操作,保证一致性。


5. 事务回滚机制(Transaction Rollback)

事务回滚机制 用于在 多个操作中出现异常时撤销已执行的操作,保证系统状态不受影响。

应用场景

  • 文件存储事务:如果某个文件修改失败,需要回滚之前的创建或删除操作。
  • 数据库操作:如用户注册时,若邮件发送失败,需要撤销已写入的数据库数据。

代码示例

try {
    builder.createFile("testDir/file1.txt", "Hello, world!")
           .modifyFile("testDir/file1.txt", "Updated content")
           .fail("模拟错误")  // 触发异常
           .createFile("testDir/file2.txt", "This won't be created!");

    builder.commit(); // 正常情况下,提交事务
} catch (Exception e) {
    System.out.println("\n🚨 " + e.getMessage());
    builder.rollback();
}

优点

保证数据一致性:出现异常时,系统能恢复到原始状态。
适用于多个操作:不仅适用于文件操作,还可用于数据库事务等。


6. 总结

设计模式 作用 代码实现
工厂模式 统一创建对象,解耦代码 FileStorageFactory
单例模式 只创建一个工厂实例,节省内存 FileStorageFactory.getInstance()
建造者模式 支持链式调用,提高可读性 FileOperationBuilder.createFile(...).modifyFile(...)
事务回滚机制 操作失败时回滚,保证数据一致性 builder.rollback()

7. 适用场景对比

设计模式 适用场景
工厂模式 需要创建多个不同但具有相同接口的对象
单例模式 需要在全局范围内共享一个对象
建造者模式 需要 逐步创建复杂对象,支持链式调用
事务回滚 需要确保多个操作的完整性,失败时可以撤销

8. 完整代码

package com.dolphinhome;

import java.io.IOException;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;

// ==================== 1. 抽象存储接口 ====================

/**
 * 定义文件存储操作的通用接口
 */
interface FileStorage {
    /**
     * 创建文件
     *
     * @param path    文件路径
     * @param content 文件内容
     * @throws IOException 可能的IO异常
     */
    void createFile(String path, String content) throws IOException;

    /**
     * 删除文件
     *
     * @param path 文件路径
     * @throws IOException 可能的IO异常
     */
    void deleteFile(String path) throws IOException;

    /**
     * 修改文件
     *
     * @param path       文件路径
     * @param newContent 新文件内容
     * @throws IOException 可能的IO异常
     */
    void modifyFile(String path, String newContent) throws IOException;
}

// ==================== 2. 本地文件存储实现 ====================

/**
 * 本地文件存储实现类,操作本地文件系统
 */
class LocalFileStorage implements FileStorage {
    @Override
    public void createFile(String path, String content) throws IOException {
        Path filePath = Paths.get(path);
        Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE_NEW);
        System.out.println("✅ [本地] 创建文件: " + path);
    }

    @Override
    public void deleteFile(String path) throws IOException {
        Path filePath = Paths.get(path);
        Files.deleteIfExists(filePath);
        System.out.println("✅ [本地] 删除文件: " + path);
    }

    @Override
    public void modifyFile(String path, String newContent) throws IOException {
        Path filePath = Paths.get(path);
        Files.write(filePath, newContent.getBytes(), StandardOpenOption.TRUNCATE_EXISTING);
        System.out.println("✅ [本地] 修改文件: " + path);
    }
}

// ==================== 3. Minio 存储实现(伪代码示例) ====================

/**
 * Minio 文件存储实现(此处仅为示例,不包含实际 Minio 代码)
 */
class MinioFileStorage implements FileStorage {
    @Override
    public void createFile(String path, String content) {
        System.out.println("✅ [Minio] 创建文件: " + path);
    }

    @Override
    public void deleteFile(String path) {
        System.out.println("✅ [Minio] 删除文件: " + path);
    }

    @Override
    public void modifyFile(String path, String newContent) {
        System.out.println("✅ [Minio] 修改文件: " + path);
    }
}

// ==================== 4. HDFS 存储实现(伪代码示例) ====================

/**
 * HDFS 文件存储实现(此处仅为示例,不包含实际 HDFS 代码)
 */
class HdfsFileStorage implements FileStorage {
    @Override
    public void createFile(String path, String content) {
        System.out.println("✅ [HDFS] 创建文件: " + path);
    }

    @Override
    public void deleteFile(String path) {
        System.out.println("✅ [HDFS] 删除文件: " + path);
    }

    @Override
    public void modifyFile(String path, String newContent) {
        System.out.println("✅ [HDFS] 修改文件: " + path);
    }
}

// ==================== 5. 工厂模式(单例模式) ====================

/**
 * 文件存储工厂,使用单例模式创建存储实例
 */
class FileStorageFactory {
    private static volatile FileStorageFactory instance;

    private FileStorageFactory() {
    }

    /**
     * 获取单例实例
     *
     * @return FileStorageFactory 实例
     */
    public static FileStorageFactory getInstance() {
        if (instance == null) {
            synchronized (FileStorageFactory.class) {
                if (instance == null) {
                    instance = new FileStorageFactory();
                }
            }
        }
        return instance;
    }

    /**
     * 获取存储实例
     *
     * @param type 存储类型 (local/minio/hdfs)
     * @return 对应的存储实例
     */
    public FileStorage getStorage(String type) {
        switch (type.toLowerCase()) {
            case "local":
                return new LocalFileStorage();
            case "minio":
                return new MinioFileStorage();
            case "hdfs":
                return new HdfsFileStorage();
            default:
                throw new IllegalArgumentException("未知存储类型: " + type);
        }
    }
}

// ==================== 6. 建造者模式(带事务回滚) ====================

/**
 * 文件操作建造者,支持事务回滚
 */
class FileOperationBuilder {
    private final FileStorage fileStorage;
    private final List<Runnable> rollbackActions = new ArrayList<>();

    public FileOperationBuilder(FileStorage fileStorage) {
        this.fileStorage = fileStorage;
    }

    // TODO: 链式调用方法
    // 创建文件
    public FileOperationBuilder createFile(String path, String content) throws IOException {
        fileStorage.createFile(path, content);

        // 记录回滚
        rollbackActions.add(() -> {
            try {
                fileStorage.deleteFile(path);
                System.out.println("🔄 回滚 - 删除文件: " + path);
            } catch (IOException e) {
                System.err.println("⚠️ 回滚失败 - 删除文件: " + path);
            }
        });

        return this;
    }

    // 删除文件
    public FileOperationBuilder deleteFile(String path) throws IOException {
        fileStorage.deleteFile(path);

        // 记录回滚(恢复删除的文件)
        rollbackActions.add(() -> {
            try {
                System.out.println("🔄 回滚 - 该文件被删除,无法恢复被删除的文件: " + path);
            } catch (Exception e) {
                System.err.println("⚠️ 回滚失败,无法恢复被删除的文件 - 恢复文件: " + path);
            }
        });

        return this;
    }

    public FileOperationBuilder modifyFile(String path, String newContent) throws IOException {
        fileStorage.modifyFile(path, newContent);

        // 记录回滚(恢复原始文件内容)
        rollbackActions.add(() -> {
            try {
                System.out.println("🔄 回滚 - 该文件被修改,但无法恢复原始内容: " + path);
            } catch (Exception e) {
                System.err.println("⚠️ 回滚失败 - 恢复文件内容: " + path);
            }
        });

        return this;
    }

    // 模拟异常
    public FileOperationBuilder fail(String reason) throws Exception {
        throw new Exception("❌ 操作失败: " + reason);
    }

    // 事务回滚
    public void rollback() {
        System.out.println("⚠️ 发生错误,执行回滚...");
        for (int i = rollbackActions.size() - 1; i >= 0; i--) {
            rollbackActions.get(i).run();
        }
    }

    // 提交事务(无异常)
    public void commit() {
        System.out.println("✅ 操作成功,提交变更!");
        rollbackActions.clear();
    }
}

// ==================== 7. 测试 ====================
public class FileStorageDemo {
    public static void main(String[] args) {
        FileStorage storage = FileStorageFactory.getInstance().getStorage("local"); // 选择本地存储
        FileOperationBuilder builder = new FileOperationBuilder(storage);

        try {
            builder.createFile("testDir/file1.txt", "Hello, world!")
                    .modifyFile("testDir/file1.txt", "Updated content")
                    .fail("模拟错误")  // 触发异常
                    .createFile("testDir/file2.txt", "This won't be created!");

            builder.commit(); // 正常情况下,提交事务
        } catch (Exception e) {
            System.out.println("\n🚨 " + e.getMessage());
            builder.rollback();
        }
    }
}

9. 代码执行结果

[本地] 创建文件: testDir/file1.txt
✅ [本地] 修改文件: testDir/file1.txt
🚨 ❌ 操作失败: 模拟错误
⚠️ 发生错误,执行回滚...
🔄 回滚 - 删除文件: testDir/file1.txt

fail("模拟错误") 触发异常时,系统会执行 事务回滚,删除 file1.txt,保证文件系统的状态一致。


10. 结论

本案例结合 工厂模式、单例模式、建造者模式、事务回滚,构建了一个 灵活、可扩展、稳定 的文件存储系统。这种设计模式的组合使用,不仅提高了代码的 可维护性,还增强了 稳定性,避免因异常导致的不一致问题。

你可以根据业务需求进一步扩展,如:

  • 增加数据库存储支持
  • 结合 AOP 自动事务管理
  • 优化异常处理逻辑

希望这篇笔记能帮助你更好地理解这些设计模式的应用!🚀


网站公告

今日签到

点亮在社区的每一天
去签到