创建对象家族:工厂方法与抽象工厂设计模式在Spring中的应用

59 阅读3分钟

前言

在软件工程中,对象创建逻辑有时会非常复杂,同时,一个产品往往需要不同版本以适应不同的运行环境或使用场景。这时候,直接在代码中硬编码对象的创建会导致高耦合和难以管理的问题。工厂方法(Factory Method)和抽象工厂(Abstract Factory)模式通过提供接口或抽象类来分离对象的实例化过程,从而提高系统的灵活性和可维护性。在这篇博文中,我们将探讨如何在Spring框架中使用这两种设计模式来创建一个为不同环境或场景量身定做的对象家族。

业务场景概述

假设我们有一个电商平台,它需要支持不同类型的支付方式,例如信用卡支付、PayPal支付等,同时也需要为不同国家/地区提供对应的税收计算方法。每种支付方式和税收计算方法都有自己的业务逻辑。此外,与这些不同的支付和税收策略相对应的日志记录系统也需要根据特定的业务规则生成。

这个电商平台就是我们的业务场景,而不同的支付方式、税收计算方法以及日志记录系统构成了我们需要创建的对象家族。

工厂方法模式

工厂方法模式提供了一个创建对象的接口,允许子类决定实例化对象的类型。在我们的电商平台中,我们可以为每种支付方式创建一个工厂。

public interface PaymentFactory {
    PaymentProcessor createPaymentProcessor();
}

public class CreditCardPaymentFactory implements PaymentFactory {
    @Override
    public PaymentProcessor createPaymentProcessor() {
        return new CreditCardPaymentProcessor();
    }
}

public class PayPalPaymentFactory implements PaymentFactory {
    @Override
    public PaymentProcessor createPaymentProcessor() {
        return new PayPalPaymentProcessor();
    }
}

public interface PaymentProcessor {
    void processPayment(BigDecimal amount);
}

// 具体的支付处理逻辑
public class CreditCardPaymentProcessor implements PaymentProcessor {
    @Override
    public void processPayment(BigDecimal amount) {
        // Credit card payment processing logic
    }
}

public class PayPalPaymentProcessor implements PaymentProcessor {
    @Override
    public void processPayment(BigDecimal amount) {
        // PayPal payment processing logic
    }
}

如上代码所示,我们定义了一个PaymentFactory接口和实现了该接口的两个具体工厂。每个具体工厂分别创建对应的支付处理器对象。

抽象工厂模式

抽象工厂模式是工厂方法模式的扩展,它用来创建一系列相关或依赖对象的工厂接口,而不需要指定它们具体的类。

在我们的业务场景中,我们不仅需要创建支付处理器,还需要创建对应的税收计算器和日志记录器。我们扩展工厂方法模式,创建一个抽象工厂模式来组合这些对象。

public interface ServiceFactory {
    PaymentProcessor createPaymentProcessor();
    TaxCalculator createTaxCalculator();
    Logger createLogger();
}

public class USServiceFactory implements ServiceFactory {
    @Override
    public PaymentProcessor createPaymentProcessor() {
        return new CreditCardPaymentProcessor();
    }

    @Override
    public TaxCalculator createTaxCalculator() {
        return new USTaxCalculator();
    }

    @Override
    public Logger createLogger() {
        return new USLogger();
    }
}

public class EUserviceFactory implements ServiceFactory {
    @Override
    public PaymentProcessor createPaymentProcessor() {
        return new PayPalPaymentProcessor();
    }

    @Override
    public TaxCalculator createTaxCalculator() {
        return new EUTaxCalculator();
    }

    @Override
    public Logger createLogger() {
        return new EULogger();
    }
}

// ... 实现对应的TaxCalculator和Logger接口

在上面的代码片段中,ServiceFactory是一个抽象工厂接口,它可以创建支付处理器、税收计算器和日志记录器。USServiceFactoryEUserviceFactory是针对不同地区的具体实现,它们分别创建适合各自地区的对象家族。

在Spring中的实现

Spring本质上是一个高级的工厂,它管理着应用中的所有对象(Bean)。通过定义配置类或使用注解,我们可以轻松地实现工厂方法和抽象工厂模式。

@Configuration
public class PaymentServiceConfiguration {
    
    @Bean
    public ServiceFactory serviceFactory(Locale locale) {
        if(Locale.US.equals(locale)) {
            return new USServiceFactory();
        } else if(Locale.FRANCE.equals(locale)) {
            return new EUserviceFactory();
        }
        // 默认工厂
        return new DefaultServiceFactory();
    }
}

// ... 实现DefaultServiceFactory和其他Bean

在上面的代码中,我们创建了一个PaymentServiceConfiguration配置类,它定义了一个根据区域设置来选择服务工厂的Spring Bean。当需要为不同国家/地区提供服务时,Spring将根据配置选择正确的工厂并创建所需的对象。

总结

通过将工厂方法和抽象工厂模式应