简单策略模式实现

发布于:2024-12-06 ⋅ 阅读:(140) ⋅ 点赞:(0)
前言

在开发Java应用程序时,良好的设计模式不仅有助于提高代码的质量和可读性,还能显著提升系统的可扩展性和灵活性。本文将用一个简单的例子来唠唠这种设计模式。本人确实代码水平一般,大家仅供参考!

一、定义策略接口

首先,我们需要定义一个通用的策略接口,所有具体的支付方式都将实现这个接口。这为我们的支付系统提供了一个统一的行为契约。

public interface PaymentStrategy {
    void execute(double amount);
}
二、实现具体策略

接下来,为每种支付方式(如信用卡、PayPal等)创建具体的策略类。这些类将实现PaymentStrategy接口,并提供特定的支付逻辑。

public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void execute(double amount) {
        System.out.println("Paid " + amount + " using Credit Card.");
    }
}

public class PayPalPayment implements PaymentStrategy {
    @Override
    public void execute(double amount) {
        System.out.println("Paid " + amount + " using PayPal.");
    }
}
三、构建策略工厂

为了管理不同类型的支付策略,我们创建一个策略工厂。该工厂会将每个策略类与一个唯一的标识符关联起来,以便根据需要动态选择并实例化相应的策略。这里我们使用Spring框架来简化依赖注入的过程,并利用@PostConstruct注解确保初始化时自动加载所有策略。

import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

@Component
public class PaymentStrategyFactory {

    private final Map<String, PaymentStrategy> strategyMap = new HashMap<>();

    // 使用构造函数注入所有的策略实例
    private final CreditCardPayment creditCardPayment;
    private final PayPalPayment payPalPayment;

    public PaymentStrategyFactory(CreditCardPayment creditCardPayment, PayPalPayment payPalPayment) {
        this.creditCardPayment = creditCardPayment;
        this.payPalPayment = payPalPayment;
    }

    /**
     * 初始化策略映射表,在应用启动时自动执行。
     */
    @PostConstruct
    private void init() {
        registerStrategy("CREDIT_CARD", creditCardPayment);
        registerStrategy("PAYPAL", payPalPayment);
    }

    /**
     * 注册新的支付策略到映射表中。
     *
     * @param type      支付方式类型标识符
     * @param strategy  对应的支付策略实现
     */
    private void registerStrategy(String type, PaymentStrategy strategy) {
        if (strategyMap.containsKey(type)) {
            throw new IllegalArgumentException("Duplicate payment strategy for type: " + type);
        }
        strategyMap.put(type, strategy);
    }

    /**
     * 根据支付方式类型获取对应的支付策略。
     *
     * @param type 支付方式类型标识符
     * @return 对应的支付策略实现,如果不存在则返回null
     */
    public PaymentStrategy getStrategy(String type) {
        return strategyMap.get(type);
    }
}
四、应用策略模式

最后,在服务层中使用策略工厂来获取并执行相应的策略。这样可以避免直接在业务逻辑中编写复杂的条件判断语句,使代码更加简洁明了。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CheckoutService {

    private final PaymentStrategyFactory paymentStrategyFactory;

    @Autowired
    public CheckoutService(PaymentStrategyFactory paymentStrategyFactory) {
        this.paymentStrategyFactory = paymentStrategyFactory;
    }

    /**
     * 完成结账流程,根据指定的支付方式进行支付。
     *
     * @param paymentMethod 支付方式类型标识符
     * @param amount        需要支付的金额
     */
    public void checkout(String paymentMethod, double amount) {
        PaymentStrategy strategy = paymentStrategyFactory.getStrategy(paymentMethod);
        if (strategy == null) {
            throw new IllegalArgumentException("Unsupported payment method: " + paymentMethod);
        }
        strategy.execute(amount);
    }
}
五、测试与验证

为了确保一切工作正常,我们可以编写单元测试来验证各个组件的功能。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class CheckoutServiceTests {

    @Autowired
    private CheckoutService checkoutService;

    @Test
    public void testCreditCardPayment() {
        checkoutService.checkout("CREDIT_CARD", 100.0);
    }

    @Test
    public void testPayPalPayment() {
        checkoutService.checkout("PAYPAL", 200.5);
    }
}
结论

通过上述步骤,我们实现了一个简单而优雅的策略模式示例。该模式不仅减少了if-elseswitch-case语句的数量,还提高了代码的可读性和可维护性。更重要的是,当有新的支付方式加入时,只需要添加一个新的策略类,并将其注册到策略工厂中即可轻松扩展系统功能,而无需修改现有代码。

此外,使用@PostConstruct注解确保了所有策略在应用程序启动时就被正确加载和初始化,进一步简化了配置过程。同时,结合Spring框架的最佳实践,使得整个系统的结构更加清晰和易于理解。