DukeDuke
主页
关于我们
主页
关于我们
  • Java

    • Java基础

      • 内存与磁盘
      • 进制转换
      • 数据存储
      • Java基本数据类型
      • HashMap
      • Java四大引用
    • JVM

      • 认识JVM
      • JVM类加载器
      • 运行时数据区
      • 执行引擎
      • 本地方法接口
      • 本地方法库
      • JVM垃圾回收
      • JVM性能监控
      • JVM调优
    • 设计模式
      • 单例模式
      • 工厂模式
      • 策略模式
      • 适配器模式
      • 建造者模式
      • 原型模式
      • 装饰器模式
      • 代理模式
      • 外观模式
      • 享元模式
      • 组合模式
      • 桥接模式
    • Java多线程

      • Java 线程基础详解
      • Java 线程池详解
      • Java ThreadLocal 详解
      • Java volatile 详解
      • Java 线程间通信详解
      • Java 线程安全详解
      • Java 线程调度详解
      • Java 线程优先级详解

      • Java 线程中断详解
      • Java 线程死锁详解
    • Java反射
    • Java 面试题

      • Java 基础概念面试题
      • Java 面向对象编程面试题
      • Java 集合框架面试题
      • Java 多线程与并发面试题
      • JVM 与内存管理面试题
      • Java I/O 与 NIO 面试题
      • Java 异常处理面试题
      • Java 反射与注解面试题
      • Java Spring 框架面试题
      • Java 数据库与 JDBC 面试题
      • Java 性能优化面试题
      • Java 实际项目经验面试题
      • Java 高级特性面试题
      • Java 面试准备建议

工厂模式

定义

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

核心思想

  • 封装创建逻辑:将对象的创建过程封装在工厂类中
  • 解耦客户端:客户端不需要知道具体对象的创建细节
  • 统一管理:所有对象的创建都通过工厂统一管理
  • 支持扩展:新增产品类型时,只需要扩展工厂,不需要修改现有代码

结构

角色组成

  1. Product(抽象产品):定义产品的公共接口
  2. ConcreteProduct(具体产品):实现抽象产品接口的具体类
  3. Factory(工厂):负责创建产品的工厂类
  4. Client(客户端):使用工厂创建产品的客户端

类图

┌─────────────────┐    ┌──────────────────┐
│     Client      │    │     Factory      │
├─────────────────┤    ├──────────────────┤
│                 │───▶│ + createProduct()│
└─────────────────┘    └──────────────────┘
                                │
                                ▼
                    ┌──────────────────┐
                    │    Product       │
                    ├──────────────────┤
                    │ + operation()    │
                    └──────────────────┘
                                ▲
                                │
        ┌─────────────────────────────────────────┐
        │                                         │
┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐
│ ConcreteProductA │    │ ConcreteProductB │    │ ConcreteProductC │
├──────────────────┤    ├──────────────────┤    ├──────────────────┤
│ + operation()    │    │ + operation()    │    │ + operation()    │
└──────────────────┘    └──────────────────┘    └──────────────────┘

工厂模式类型

1. 简单工厂模式(Simple Factory)

电商系统中的商品类型管理,需要根据商品类型创建不同的商品对象。

抽象产品接口

public interface Product {
    String getProductName();
    BigDecimal getPrice();
    String getDescription();
}

具体产品类

// 电子产品
@Component
public class ElectronicProduct implements Product {
    private String name;
    private BigDecimal price;
    private String brand;

    public ElectronicProduct(String name, BigDecimal price, String brand) {
        this.name = name;
        this.price = price;
        this.brand = brand;
    }

    @Override
    public String getProductName() {
        return name;
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }

    @Override
    public String getDescription() {
        return "电子产品 - " + brand + " " + name;
    }
}

// 服装产品
@Component
public class ClothingProduct implements Product {
    private String name;
    private BigDecimal price;
    private String size;

    public ClothingProduct(String name, BigDecimal price, String size) {
        this.name = name;
        this.price = price;
        this.size = size;
    }

    @Override
    public String getProductName() {
        return name;
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }

    @Override
    public String getDescription() {
        return "服装产品 - " + name + " (尺码: " + size + ")";
    }
}

// 食品产品
@Component
public class FoodProduct implements Product {
    private String name;
    private BigDecimal price;
    private LocalDate expiryDate;

    public FoodProduct(String name, BigDecimal price, LocalDate expiryDate) {
        this.name = name;
        this.price = price;
        this.expiryDate = expiryDate;
    }

    @Override
    public String getProductName() {
        return name;
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }

    @Override
    public String getDescription() {
        return "食品产品 - " + name + " (过期时间: " + expiryDate + ")";
    }
}

简单工厂类

@Service
public class ProductFactory {

    public Product createProduct(String productType, String name, BigDecimal price, Map<String, Object> attributes) {
        switch (productType.toLowerCase()) {
            case "electronic":
                String brand = (String) attributes.get("brand");
                return new ElectronicProduct(name, price, brand);

            case "clothing":
                String size = (String) attributes.get("size");
                return new ClothingProduct(name, price, size);

            case "food":
                LocalDate expiryDate = (LocalDate) attributes.get("expiryDate");
                return new FoodProduct(name, price, expiryDate);

            default:
                throw new IllegalArgumentException("未知的商品类型: " + productType);
        }
    }
}

客户端使用

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductFactory productFactory;

    @PostMapping("/create")
    public ResponseEntity<String> createProduct(@RequestBody ProductRequest request) {
        try {
            Product product = productFactory.createProduct(
                request.getType(),
                request.getName(),
                request.getPrice(),
                request.getAttributes()
            );

            return ResponseEntity.ok("商品创建成功: " + product.getDescription());
        } catch (Exception e) {
            return ResponseEntity.badRequest().body("商品创建失败: " + e.getMessage());
        }
    }
}

// 请求DTO
public class ProductRequest {
    private String type;
    private String name;
    private BigDecimal price;
    private Map<String, Object> attributes;

    // getters and setters
}

2. 工厂方法模式(Factory Method)

支付系统中的不同支付方式处理,每种支付方式需要不同的处理逻辑。

抽象产品接口

public interface PaymentProcessor {
    PaymentResult process(PaymentRequest request);
    boolean supports(String paymentType);
}

具体产品类

// 支付宝支付处理器
@Component
public class AlipayProcessor implements PaymentProcessor {

    @Override
    public PaymentResult process(PaymentRequest request) {
        // 模拟支付宝支付处理逻辑
        System.out.println("处理支付宝支付: " + request.getAmount());

        // 调用支付宝API
        boolean success = callAlipayAPI(request);

        return PaymentResult.builder()
                .success(success)
                .transactionId(success ? generateTransactionId() : null)
                .message(success ? "支付宝支付成功" : "支付宝支付失败")
                .build();
    }

    @Override
    public boolean supports(String paymentType) {
        return "alipay".equalsIgnoreCase(paymentType);
    }

    private boolean callAlipayAPI(PaymentRequest request) {
        // 模拟支付宝API调用
        return Math.random() > 0.1; // 90%成功率
    }

    private String generateTransactionId() {
        return "ALI" + System.currentTimeMillis();
    }
}

// 微信支付处理器
@Component
public class WechatPayProcessor implements PaymentProcessor {

    @Override
    public PaymentResult process(PaymentRequest request) {
        // 模拟微信支付处理逻辑
        System.out.println("处理微信支付: " + request.getAmount());

        // 调用微信支付API
        boolean success = callWechatPayAPI(request);

        return PaymentResult.builder()
                .success(success)
                .transactionId(success ? generateTransactionId() : null)
                .message(success ? "微信支付成功" : "微信支付失败")
                .build();
    }

    @Override
    public boolean supports(String paymentType) {
        return "wechat".equalsIgnoreCase(paymentType);
    }

    private boolean callWechatPayAPI(PaymentRequest request) {
        // 模拟微信支付API调用
        return Math.random() > 0.1; // 90%成功率
    }

    private String generateTransactionId() {
        return "WX" + System.currentTimeMillis();
    }
}

// 银行卡支付处理器
@Component
public class BankCardProcessor implements PaymentProcessor {

    @Override
    public PaymentResult process(PaymentRequest request) {
        // 模拟银行卡支付处理逻辑
        System.out.println("处理银行卡支付: " + request.getAmount());

        // 调用银行API
        boolean success = callBankAPI(request);

        return PaymentResult.builder()
                .success(success)
                .transactionId(success ? generateTransactionId() : null)
                .message(success ? "银行卡支付成功" : "银行卡支付失败")
                .build();
    }

    @Override
    public boolean supports(String paymentType) {
        return "bankcard".equalsIgnoreCase(paymentType);
    }

    private boolean callBankAPI(PaymentRequest request) {
        // 模拟银行API调用
        return Math.random() > 0.1; // 90%成功率
    }

    private String generateTransactionId() {
        return "BANK" + System.currentTimeMillis();
    }
}

抽象工厂接口

public interface PaymentProcessorFactory {
    PaymentProcessor createProcessor(String paymentType);
}

具体工厂类

@Service
public class PaymentProcessorFactoryImpl implements PaymentProcessorFactory {

    private final List<PaymentProcessor> processors;

    @Autowired
    public PaymentProcessorFactoryImpl(List<PaymentProcessor> processors) {
        this.processors = processors;
    }

    @Override
    public PaymentProcessor createProcessor(String paymentType) {
        return processors.stream()
                .filter(processor -> processor.supports(paymentType))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("不支持的支付方式: " + paymentType));
    }
}

客户端使用

@RestController
@RequestMapping("/payments")
public class PaymentController {

    @Autowired
    private PaymentProcessorFactory paymentProcessorFactory;

    @PostMapping("/process")
    public ResponseEntity<PaymentResult> processPayment(@RequestBody PaymentRequest request) {
        try {
            PaymentProcessor processor = paymentProcessorFactory.createProcessor(request.getPaymentType());
            PaymentResult result = processor.process(request);

            return ResponseEntity.ok(result);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(
                PaymentResult.builder()
                    .success(false)
                    .message("支付处理失败: " + e.getMessage())
                    .build()
            );
        }
    }
}

// 请求和结果DTO
public class PaymentRequest {
    private String paymentType;
    private BigDecimal amount;
    private String orderId;
    private String userId;

    // getters and setters
}

public class PaymentResult {
    private boolean success;
    private String transactionId;
    private String message;

    // builder pattern implementation
}

3. 抽象工厂模式(Abstract Factory)

电商平台的多租户系统,不同租户需要不同的 UI 主题、数据库配置和缓存策略。

抽象产品接口

// UI主题接口
public interface UITheme {
    String getPrimaryColor();
    String getSecondaryColor();
    String getLogoUrl();
    String getThemeName();
}

// 数据库配置接口
public interface DatabaseConfig {
    String getUrl();
    String getUsername();
    String getPassword();
    int getMaxConnections();
}

// 缓存策略接口
public interface CacheStrategy {
    void put(String key, Object value);
    Object get(String key);
    void remove(String key);
    void clear();
}

具体产品类

// 企业版UI主题
@Component
public class EnterpriseUITheme implements UITheme {

    @Override
    public String getPrimaryColor() {
        return "#1a365d";
    }

    @Override
    public String getSecondaryColor() {
        return "#2d3748";
    }

    @Override
    public String getLogoUrl() {
        return "/assets/enterprise-logo.png";
    }

    @Override
    public String getThemeName() {
        return "enterprise";
    }
}

// 个人版UI主题
@Component
public class PersonalUITheme implements UITheme {

    @Override
    public String getPrimaryColor() {
        return "#e53e3e";
    }

    @Override
    public String getSecondaryColor() {
        return "#f56565";
    }

    @Override
    public String getLogoUrl() {
        return "/assets/personal-logo.png";
    }

    @Override
    public String getThemeName() {
        return "personal";
    }
}

// MySQL数据库配置
@Component
public class MySQLConfig implements DatabaseConfig {

    @Value("${mysql.url}")
    private String url;

    @Value("${mysql.username}")
    private String username;

    @Value("${mysql.password}")
    private String password;

    @Override
    public String getUrl() {
        return url;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public int getMaxConnections() {
        return 100;
    }
}

// PostgreSQL数据库配置
@Component
public class PostgreSQLConfig implements DatabaseConfig {

    @Value("${postgresql.url}")
    private String url;

    @Value("${postgresql.username}")
    private String username;

    @Value("${postgresql.password}")
    private String password;

    @Override
    public String getUrl() {
        return url;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public int getMaxConnections() {
        return 50;
    }
}

// Redis缓存策略
@Component
public class RedisCacheStrategy implements CacheStrategy {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void put(String key, Object value) {
        redisTemplate.opsForValue().set(key, value, Duration.ofHours(1));
    }

    @Override
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    @Override
    public void remove(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public void clear() {
        // 清除所有缓存
        Set<String> keys = redisTemplate.keys("*");
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }
}

// 内存缓存策略
@Component
public class MemoryCacheStrategy implements CacheStrategy {

    private final Map<String, Object> cache = new ConcurrentHashMap<>();

    @Override
    public void put(String key, Object value) {
        cache.put(key, value);
    }

    @Override
    public Object get(String key) {
        return cache.get(key);
    }

    @Override
    public void remove(String key) {
        cache.remove(key);
    }

    @Override
    public void clear() {
        cache.clear();
    }
}

抽象工厂接口

public interface TenantFactory {
    UITheme createUITheme();
    DatabaseConfig createDatabaseConfig();
    CacheStrategy createCacheStrategy();
}

具体工厂类

// 企业版工厂
@Service("enterpriseFactory")
public class EnterpriseTenantFactory implements TenantFactory {

    @Autowired
    private EnterpriseUITheme uiTheme;

    @Autowired
    private MySQLConfig databaseConfig;

    @Autowired
    private RedisCacheStrategy cacheStrategy;

    @Override
    public UITheme createUITheme() {
        return uiTheme;
    }

    @Override
    public DatabaseConfig createDatabaseConfig() {
        return databaseConfig;
    }

    @Override
    public CacheStrategy createCacheStrategy() {
        return cacheStrategy;
    }
}

// 个人版工厂
@Service("personalFactory")
public class PersonalTenantFactory implements TenantFactory {

    @Autowired
    private PersonalUITheme uiTheme;

    @Autowired
    private PostgreSQLConfig databaseConfig;

    @Autowired
    private MemoryCacheStrategy cacheStrategy;

    @Override
    public UITheme createUITheme() {
        return uiTheme;
    }

    @Override
    public DatabaseConfig createDatabaseConfig() {
        return databaseConfig;
    }

    @Override
    public CacheStrategy createCacheStrategy() {
        return cacheStrategy;
    }
}

客户端使用

@RestController
@RequestMapping("/tenant")
public class TenantController {

    @Autowired
    @Qualifier("enterpriseFactory")
    private TenantFactory enterpriseFactory;

    @Autowired
    @Qualifier("personalFactory")
    private TenantFactory personalFactory;

    @GetMapping("/config/{tenantType}")
    public ResponseEntity<TenantConfig> getTenantConfig(@PathVariable String tenantType) {
        TenantFactory factory = getFactoryByType(tenantType);

        TenantConfig config = TenantConfig.builder()
                .uiTheme(factory.createUITheme())
                .databaseConfig(factory.createDatabaseConfig())
                .cacheStrategy(factory.createCacheStrategy())
                .build();

        return ResponseEntity.ok(config);
    }

    private TenantFactory getFactoryByType(String tenantType) {
        switch (tenantType.toLowerCase()) {
            case "enterprise":
                return enterpriseFactory;
            case "personal":
                return personalFactory;
            default:
                throw new IllegalArgumentException("未知的租户类型: " + tenantType);
        }
    }
}

// 配置DTO
public class TenantConfig {
    private UITheme uiTheme;
    private DatabaseConfig databaseConfig;
    private CacheStrategy cacheStrategy;

    // builder pattern implementation
}

运行结果

简单工厂模式示例

POST /products/create
{
    "type": "electronic",
    "name": "iPhone 15",
    "price": 5999.00,
    "attributes": {
        "brand": "Apple"
    }
}

响应: 商品创建成功: 电子产品 - Apple iPhone 15

工厂方法模式示例

POST /payments/process
{
    "paymentType": "alipay",
    "amount": 100.00,
    "orderId": "ORD001",
    "userId": "USER001"
}

响应: {
    "success": true,
    "transactionId": "ALI1703123456789",
    "message": "支付宝支付成功"
}

抽象工厂模式示例

GET /tenant/config/enterprise

响应: {
    "uiTheme": {
        "primaryColor": "#1a365d",
        "secondaryColor": "#2d3748",
        "logoUrl": "/assets/enterprise-logo.png",
        "themeName": "enterprise"
    },
    "databaseConfig": {
        "url": "jdbc:mysql://localhost:3306/enterprise_db",
        "username": "enterprise_user",
        "password": "******",
        "maxConnections": 100
    },
    "cacheStrategy": "Redis"
}

优点

  1. 封装创建逻辑:将对象的创建过程封装在工厂中,客户端不需要知道具体实现
  2. 解耦:客户端与具体产品类解耦,只依赖抽象接口
  3. 易于扩展:添加新产品时,只需要扩展工厂,不需要修改现有代码
  4. 统一管理:所有对象的创建都通过工厂统一管理
  5. 支持多态:通过接口实现多态,提高代码的灵活性

缺点

  1. 增加复杂度:引入了额外的抽象层,增加了系统的复杂度
  2. 类数量增加:工厂方法模式会导致类数量激增
  3. 可能过度设计:简单场景下可能显得过于复杂
  4. 违反开闭原则:简单工厂模式在添加新产品时需要修改工厂类

应用场景

  1. 商品管理系统:根据商品类型创建不同的商品对象
  2. 支付系统:根据支付方式创建不同的支付处理器
  3. 多租户系统:根据租户类型创建不同的配置组合
  4. 日志系统:根据日志级别创建不同的日志记录器
  5. 数据库连接:根据数据库类型创建不同的连接对象
  6. UI 组件:根据主题创建不同的 UI 组件

与其他模式的关系

  • 与单例模式结合:工厂类可以使用单例模式确保全局唯一
  • 与策略模式结合:工厂模式创建策略对象,策略模式执行具体算法
  • 与建造者模式区别:工厂模式关注对象的创建,建造者模式关注对象的构建过程
  • 与原型模式区别:工厂模式创建新对象,原型模式克隆现有对象

最佳实践

  1. 选择合适的工厂类型:

    • 简单工厂:产品种类较少且相对固定
    • 工厂方法:需要为每种产品提供专门创建逻辑
    • 抽象工厂:需要创建一系列相关产品
  2. 工厂类设计:

    • 确保工厂类职责单一
    • 考虑使用依赖注入管理工厂对象
    • 合理命名工厂方法
  3. 产品接口设计:

    • 确保产品接口足够抽象
    • 考虑产品的共同特征
    • 支持未来的扩展
  4. 错误处理:

    • 对不支持的产品类型提供明确的错误信息
    • 考虑使用异常处理机制

总结

工厂模式是一种非常重要的创建型设计模式,它通过封装对象的创建过程来提高代码的可维护性和扩展性。在实际开发中,工厂模式经常与 Spring 框架的依赖注入机制结合使用,形成更加灵活和强大的解决方案。

选择合适的工厂模式类型对于项目的成功至关重要,需要根据具体的业务场景和需求来做出决策。同时,要注意避免过度设计,在简单场景下使用简单工厂模式就足够了。

最近更新:: 2025/12/29 11:07
Contributors: Duke
Prev
单例模式
Next
策略模式