Java设计模式系列 - 策略模式:灵活选择算法的行为艺术

        在软件开发过程中,设计模式是一套精心设计的工具箱,以独特的魅力优雅地帮助开发者构建出灵活且易于维护的系统,今天我们就深入探讨一下设计模式中的策略模式

策略模式的定义与核心思想

        策略模式定义了一系列算法,并封装起来,是它们可以相互替换,此模式让算法的变化独立于使用算法的客户,比如扫码支付:当客户扫码支付费用时,应用会根据用户选择的支付方式匹配对应支付算法完成支付行为

策略模式的角色

  1. 策略接口:公共算法接口,定义抽象的公共算法,目的是让不同算法可以自由切换
  2. 具体策略类:实现了策略接口的类,提供算法的具体实现
  3. 上下文类(策略执行者):维护了对策略对象的引用,根据客户请求动态地引用具体策略类

策略模式的优点

  1. 灵活性:策略模式提供了在运行时选择算法的能力
  2. 开闭原则和可扩展性:不修改现有代码,通过新增策略类,轻松地扩展系统功能

示例代码

策略模式包管理规范

src/  
|-- main/  
|  |-- java/  
|     |-- com/  
|        |-- company/  
|           |-- project/  
|              |-- strategy/ #策略模式的包
|                 |-- PaymentStrategy.java #支付算法策略模式接口
|                    |-- impl/ #具体策略类的包
|                       |-- AliPayStrategy.java #支付宝支付策略
|                       |-- WechatPayStrategy.java #微信支付策略
|                       |-- UnionPayStrategy.java #银联支付策略
|              |-- context/ #上下文相关的包
|                 |-- PaymentContext.java #支付上下文类,负责维护对策略对象的引用

策略接口

/**
 * 支付算法策略模式接口
 * @author muze
 */
public interface PaymentStrategy {
    /**
     * 支付
     * @param amount 支付总额
     */
    void pay(double amount);
}

具体策略类

支付宝支付策略
/**
 * 支付宝支付算法策略
 * @author muze
 */
@Slf4j
public class AliPayStrategy implements PaymentStrategy {
    /**
     * 支付
     * @param amount 支付总额
     */
    @Override
    public void pay(double amount) {
        // TODO:支付宝支付算法具体实现
        log.info("使用支付宝支付了:{}元", amount);
    }
}
微信支付策略
/**
 * 微信支付算法策略
 * @author muze
 */
@Slf4j
public class WechatPayStrategy implements PaymentStrategy {
    /**
     * 支付
     * @param amount 支付总额
     */
    @Override
    public void pay(double amount) {
        // TODO:微信支付算法具体实现
        log.info("使用微信支付了:{}元", amount);
    }
}
银联支付策略
/**
 * 银联支付算法策略
 * @author muze
 */
@Slf4j
public class UnionPayStrategy implements PaymentStrategy {
    /**
     * 支付
     * @param amount 支付总额
     */
    @Override
    public void pay(double amount) {
        // TODO:银联支付算法具体实现
        log.info("使用银联支付了:{}元", amount);
    }
}
默认支付策略
/**
 * 默认支付算法策略
 * @author muze
 */
@Slf4j
public class DefaultPayStrategy implements PaymentStrategy {
    /**
     * 支付
     * @param amount 支付总额
     */
    @Override
    public void pay(double amount) {
        // TODO:默认支付算法具体实现
        log.info("使用默认支付了:{}元", amount);
    }
}

支付上下文类

/**
 * 支付上下文类
 * @author muze
 */
@Slf4j
public class PaymentContext {
    private PaymentStrategy paymentStrategy;
    public PaymentContext() {}
    public PaymentContext(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    public void executePay(double amount) {
        paymentStrategy.pay(amount);
    }
}

应用策略模式

在业务层我们可以这样使用策略模式

基础版

Spring没有管理Bean

@Service
public class PaymentServiceImpl implements IPaymentService {
    @Override
    public String pay(String paymentStrategy, double amount) {
        PaymentStrategy strategy;
        if ("aliPayStrategy".equals(paymentStrategy)) {
            strategy = new AliPayStrategy();
        } else if ("wechatPayStrategy".equals(paymentStrategy)) {
            strategy = new WechatPayStrategy();
        } else if ("unionPayStrategy".equals(paymentStrategy)) {
            strategy = new UnionPayStrategy();
        } else {
            strategy = new DefaultPayStrategy();
        }
        PaymentContext paymentContext = new PaymentContext(strategy);
        paymentContext.pay(amount);
        return "支付成功";
    }
}
进阶版

Spring管理了Bean

@Configuration
public class PaymentConfig {
    @Bean  
    public PaymentStrategy alipayStrategy() {
        return new AlipayStrategy();
    }
    @Bean
    public PaymentStrategy wechatPayStrategy() {
        return new WechatPayStrategy();
    }
    @Bean
    public PaymentStrategy unionPayStrategy() {
        return new UnionPayStrategy();
    }
    @Bean
    public PaymentStrategy defaultPayStrategy() {
        return new DefaultPayStrategy();
    }
    @Bean
    public PaymentContext paymentContext() {
        return new PaymentContext();
    }
}
@Service
public class PaymentServiceImpl implements IPaymentService {
    @Autowired
    private PaymentContext paymentContext;
    @Autowired
    private AlipayStrategy alipayStrategy;
    @Autowired
    private WechatPayStrategy wechatPayStrategy;
    @Autowired
    private UnionPayStrategy unionPayStrategy;
    @Autowired
    private DefaultPayStrategy defaultPayStrategy;

    @Override
    public String pay(String paymentStrategy, double amount) {
        PaymentStrategy strategy;
        if ("aliPayStrategy".equals(paymentStrategy)) {
            strategy = aliPayStrategy;
        } else if ("wechatPayStrategy".equals(paymentStrategy)) {
            strategy = wechatPayStrategy;
        } else if ("unionPayStrategy".equals(paymentStrategy)) {
            strategy = unionPayStrategy;
        } else {
            strategy = defaultPayStrategy;
        }
        paymentContext.setPaymentStrategy(strategy);
        paymentContext.pay(amount);
        return "支付成功";
    }
}
优雅版

Spring管理了Bean

在具体策略类上打@Service,在支付上下文类打@Component

@Service
public class PaymentServiceImpl implements IPaymentService {
    @Autowired
    private PaymentContext paymentContext;
    @Autowired
    private Map<String, PaymentStrategy> paymentStrategyMap;
    @Autowired
    private DefaulPayStrategy defaulPayStrategy;

    @Override
    public String pay(String paymentStrategy, double amount) {
        PaymentStrategy strategy = paymentStrategyMap.getOrDefault(paymentStrategy, defaulPayStrategy);
        paymentContext.setPaymentStrategy(strategy);
        paymentContext.pay(amount);
        return "支付成功";
    }
}

        至此一个以支付算法为例的策略模式代码就演示完成了,由此可以看出,系统在运行过程种处理请求时可以灵活地根据客户的实际情况去匹配对应的具体策略类,再通过上下文类进行算法处理

总结

        策略模式时一种强大地设计模式,它通过定义和封装一系列算法,使得算法的变化独立于使用算法的客户。通过接口和类的实现,我们可以轻松地应用策略模式来构建灵活且可扩展地系统。简单来说就是当你遇到一种行为有不同实现的需求时就可以考虑使用策略模式,希望这篇文章对你有所帮助

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值