策略模式+工厂模式+模板方法模式与spring的结合

一、现在有很多关于策略模式,工厂模式和模板方法的介绍。但是基本都是main方法来展示的,不太清楚怎么移植到自己代码中。这里将其中if else当很多的时候,通过这三种模式与spring结合起来。

这个是当计算商品的价格时候,通过不同会员类型来计算,应该支付的价格的伪代码。可以看到根据三种不同类型,拥有不同折扣。其实看到这个代码,并不算麻烦。如果这一块经常变动,这就会导致这个算法越来越臃肿,进而得到的后果就是代码行数越来越多,开发人员改动一点点代码都需要把所有功能全部都回归一遍。下面通过几种模式的运用,将这一块解耦开来。

public BigDecimal quotePrice(BigDecimal orderPrice, String type) {

        if ("particularlyVip".equals(type)) {
            return orderPrice.multiply(new BigDecimal(0.95));
        }

        if ("Vip".equals(type)) {
            return orderPrice.multiply(new BigDecimal(0.9));
        }

        if ("Vip".equals(type)) {
            return orderPrice.multiply(new BigDecimal(0.8));
        }
     
        return orderPrice;
    }

首先定义一个service的接口,定义不同策略类。让不同策略类实现计算价格的这一接口。

public interface UserPayService {

    /**
     * 计算应付价格
     */
    BigDecimal quotePrice(BigDecimal orderPrice);
}

定义一个抽象模板类,实现service和InitializingBean 接口,afterPropertiesSet用于注册到工厂方法之中。这样剩下的策略方法只用继承UserPayTemplate ,实现quotePrice这个方法。

public abstract class UserPayTemplate implements UserPayService,InitializingBean {

    private String type;
    
    public UserPayTemplate(String type) {
        this.type = type;
    }

    @Override
    public  abstract  BigDecimal quotePrice(BigDecimal orderPrice);

    @Override
    public void afterPropertiesSet() throws Exception {
        UserPayStrategyFactory.register(type,this);
    }
}

三种策略方法,继承抽象模板类去实现具体计算应付价格的具体逻辑。

@Service
public class ParticularlyVipPayService extends UserPayTemplate {

    private static final String type = "particularlyVip";

    public ParticularlyVipPayService() {
        super(type);
    }

    @Override
    public BigDecimal quotePrice(BigDecimal orderPrice) {
        return orderPrice.multiply(new BigDecimal(0.95));
    }
}

@Service
public class SuperVipPayService extends UserPayTemplate {
    private static final String type = "SuperVip";


    public SuperVipPayService() {
        super(type);
    }

    @Override
    public BigDecimal quotePrice(BigDecimal orderPrice) {
        return orderPrice.multiply(new BigDecimal(0.8));
    }
}

@Service
public class VipPayService extends UserPayTemplate {
    private static final String type = "Vip";

    public VipPayService() {
        super(type);
    }


    @Override
    public BigDecimal quotePrice(BigDecimal orderPrice) {
        return orderPrice.multiply(new BigDecimal(0.9));
    }
    
}

定义一个工厂方法,让工厂方法与不同策略结合起来。在选择不同策略的时候,通过工厂类来创造这个方法。

public class UserPayStrategyFactory {

    private static Map<String,UserPayService> services = new ConcurrentHashMap<String,UserPayService>();

    public  static UserPayService getByUserType(String type){
        return services.get(type);
    }

    public static void register(String userType,UserPayService userPayService){
        Assert.notNull(userType,"type can't be null");
        services.put(userType,userPayService);
    }
}

下面是Controller的测试方法,通过这种将数据库里面的数据和刚刚定义的不同策略结合起来,并查看测试结果。

 @PostMapping("/getRequest")
    public String testRequestBody(HttpServletRequest request, HttpServletResponse response) throws IOException {
   
        String type1 = "particularlyVip";
        UserPayService userPayService = UserPayStrategyFactory.getByUserType(type1);
        BigDecimal quote = userPayService.quotePrice(new BigDecimal(300));
        System.out.println("particularlyVip会员商品的最终价格为:" + quote.doubleValue());
        String type2 = "Vip";
        UserPayService userPayService2 = UserPayStrategyFactory.getByUserType(type2);
        BigDecimal quote2 = userPayService2.quotePrice(new BigDecimal(300));
        System.out.println("vip会员商品的最终价格为:" + quote2.doubleValue());
        String type3= "SuperVip";
        UserPayService userPayService3 = UserPayStrategyFactory.getByUserType(type3);
        BigDecimal quote3 = userPayService3.quotePrice(new BigDecimal(300));
        System.out.println("SuperVip会员商品的最终价格为:" + quote3.doubleValue());
        return "success";
    }

测试结果:

particularlyVip会员商品的最终价格为:285.0
vip会员商品的最终价格为:270.0
SuperVip会员商品的最终价格为:240.0
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值