基于订单批量支付场景,对策略模式和简单工厂模式进行简单实现
以下是菜鸟教程对策略模式的介绍: 策略模式
在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。
策略模式主要有三个角色:
我们使用接口来实现抽象策略,规定了支付的公共方法,根据传入的用户名和支付金额进行结算。
package knowledege.designPattern.strategy.test1;
import java.math.BigDecimal;
public interface PayStrategy {
void pay(String name, BigDecimal money);
}
初始化微信和支付宝两种支付策略
package knowledege.designPattern.strategy.test1;
import java.math.BigDecimal;
public class AliPayStrategy implements PayStrategy{
@Override
public void pay(String name, BigDecimal money) {
System.out.println("[" +name+ "]使用支付宝支付..." + money + "元");
}
}
package knowledege.designPattern.strategy.test1;
import java.math.BigDecimal;
public class WeChatPayStrategy implements PayStrategy{
@Override
public void pay(String name, BigDecimal money) {
System.out.println("[" +name+ "]使用微信支付..." + money + "元");
}
}
提供设置策略和执行策略的方法
package knowledege.designPattern.strategy.test1;
import java.math.BigDecimal;
public class PayContext {
private PayStrategy payStrategy;
public PayContext(){}
public void setPayStrategy(PayStrategy payStrategy){
this.payStrategy = payStrategy;
}
public void executePayStrategy(String name, BigDecimal money){
payStrategy.pay(name, money);
}
}
定义枚举并支持静态根据支付方式获取枚举
package knowledege.designPattern.strategy.test1;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum PayWayEnum {
PAY_ALI("01","支付宝"),
PAY_WE_CHAT("02","微信");
public final String payWay;
public final String payDesc;
public static PayWayEnum getEnumByWay(String payWay){
for(PayWayEnum enums: PayWayEnum.values()){
if(enums.payWay.equals(payWay)){
return enums;
}
}
return null;
}
}
public interface StrategyFactory {
PayStrategy initStrategy();
}
package knowledege.designPattern.strategy.test1;
import java.util.Objects;
public class StrategySimpleFactory {
public static PayStrategy initStrategy(String payWay){
PayWayEnum payWayEnum = PayWayEnum.getEnumByWay(payWay);
if (Objects.isNull(payWayEnum)) {
return null;
}
PayStrategy strategy = null;
switch (payWayEnum) {
case PAY_ALI:
strategy = new AliPayStrategy();
break;
case PAY_WE_CHAT:
strategy = new WeChatPayStrategy();
break;
}
return strategy;
}
}
package knowledege.designPattern.strategy.test1;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderTestDTO {
Integer orderNum;
String payPersonName;
String payWay;
BigDecimal payMoney;
}
模拟对订单进行批量支付
package knowledege.designPattern.strategy.test1;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class test1 {
public static void main(String[] args) {
List<OrderTestDTO> orderList = initOrders();
batchPay(orderList);
}
/**
* 获取订单
*/
public static List<OrderTestDTO> initOrders(){
List<OrderTestDTO> orderList = new ArrayList<>();
orderList.add(new OrderTestDTO(1,"aaa","01",new BigDecimal("99")));
orderList.add(new OrderTestDTO(2,"aaa","02",new BigDecimal("20")));
orderList.add(new OrderTestDTO(3,"bbb","01",new BigDecimal("17")));
orderList.add(new OrderTestDTO(4,"ccc","02",new BigDecimal("19.88")));
return orderList;
}
/**
* 订单批量支付
*/
public static void batchPay(List<OrderTestDTO> orderList){
PayContext payContext = new PayContext();
orderList.forEach( order -> {
PayStrategy strategy = StrategySimpleFactory.initStrategy(order.getPayWay());
payContext.setPayStrategy(strategy);
payContext.executePayStrategy(order.getPayPersonName(), order.getPayMoney());
});
}
}
如果需要扩展一种支付方式,才能看出策略+工厂模式的真正优点。
下面我们模拟扩展一种支付方式:银行卡支付
package knowledege.designPattern.strategy.test1;
import java.math.BigDecimal;
public class CardStrategy implements PayStrategy{
@Override
public void pay(String name, BigDecimal money) {
System.out.println("[" +name+ "]使用银行卡支付..." + money + "元");
}
}
PAY_CARD("03","银行卡"),
case PAY_CARD:
strategy = new CardStrategy();
break;