在商城系统中使用设计模式----策略模式之在spring中使用策略模式 ...

在商城系统中使用设计模式----策略模式之在spring中使用策略模式
1.前言:

这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式。

2.问题:

在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

在spring 中,策略对象在正常情况下是,在启动Spring容器对时候,已经将策略对象加载创建完成成为bean。

我们如何在Spring中正确对使用策略模式,这样又会发生什么问题呢?

3.使用场景: 

场景:商城活动中有几种,满减,打折,送积分.我们要获取商品对最终价格。

4.实现

步骤一.创建接口类

复制代码
public interface GoodsActivity {

/**
 * 获取应该支付的金额
 * @param amount 商品的单价
 * @return
 */
BigDecimal getPayPrice(BigDecimal amount);

}
复制代码
步骤二.实现接口,并添加@Component注解

复制代码
@Component
public class DiscountActivity implements GoodsActivity {

//折扣
private double discount ;

@Override
public BigDecimal getPayPrice(BigDecimal amount) {

    //假装从数据库的配置表取折扣
    discount = 8.0;

    return new BigDecimal(discount).multiply(amount).divide(new BigDecimal(10));
}

}
复制代码
复制代码
@Component
public class FullReduceActivity implements GoodsActivity {

//满多少
private BigDecimal fullAmount;

//减多少
private BigDecimal reductionAmount ;

@Override
public BigDecimal getPayPrice(BigDecimal amount) {

    //假装从数据库的配置表取配置数据
    fullAmount = new BigDecimal(300);

    reductionAmount  = new BigDecimal(100);

    return amount.compareTo(fullAmount)>=0?amount.subtract(reductionAmount):amount;
}

}
复制代码
复制代码
@Component
public class IntegralActivity implements GoodsActivity {

//抵扣的积分  10积分=1元
private int integral = 100;

@Override
public BigDecimal getPayPrice(BigDecimal amount) {
    return amount.subtract(new BigDecimal(integral/10));
}

}
复制代码
步骤三.创建context

复制代码
public class GoodsActivityContext {

private GoodsActivity goodsActivity;

public GoodsActivityContext(GoodsActivity goodsActivity){
    this.goodsActivity=goodsActivity;
}

/**
 * 获取商品价格
 * @param amount
 * @return
 */
public BigDecimal getPrice(BigDecimal amount){
    return goodsActivity.getPayPrice(amount);
}

}
复制代码
步骤四.在控制层中调用策略模式

复制代码
@RestController
public class ActivityController{

@Autowired
private DiscountActivity discountActivity;

@Autowired
private FullReduceActivity fullReduceActivity;

@Autowired
private IntegralActivity integralActivity;
/**
 * 获取最终售价
 *  (这样的控制层写法很不友好,需要写大量的代码去实现)
 *      为了解决这个问题,将引用工厂模式...
 *
 *      工厂是创建型模式,它的作用就是创建对象;
 *      策略是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;
 *
 *  解决不同的问题
 * 工厂模式是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。
 * 策略模式是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。
 *
 * 工厂相当于黑盒子,策略相当于白盒子;
 *
 *
 * @param activityType
 * @param amount
 * @return
 */
@RequestMapping("getLastPrice")
public ResponseResult getLastPrice(String activityType,BigDecimal amount){

    ResponseResult responseResult = ResponseResult.getInstance();

    GoodsActivityContext goodsActivityContext;

    //根据活动类型获取最终售价
    switch (activityType){
        case "discount":
            goodsActivityContext = new GoodsActivityContext(discountActivity);
            break;
        case "fullReduce":
            goodsActivityContext = new GoodsActivityContext(fullReduceActivity);
            break;
        case "integral":
            goodsActivityContext = new GoodsActivityContext(integralActivity);
            break;
        default:
            responseResult.setCode(1);
            responseResult.setMsg("数据类型错误");
            responseResult.setData(null);
            return responseResult;
    }

    responseResult.setCode(0);
    responseResult.setMsg("操作成功");
    responseResult.setData(goodsActivityContext.getPrice(amount));

    return responseResult;
}

}
复制代码

总结:按照注释说明,很明显我们需要优化这个策略模式。

步骤三:(2) 引入工厂模式,对策略对象进行管理

复制代码
@Component
public class GoodsActivityStrategyFactory {

@Autowired
private Map<String,GoodsActivity> goodsActivityMap;

/**
 * 根据活动类型 获取所对应的策略
 * @param activityType
 */
public GoodsActivityContext getGoodsActivityStrategy(String activityType){

    GoodsActivityContext goodsActivityContext;

    switch (activityType){
        case "discount":
            goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("discountActivity"));
            break;
        case "fullReduce":
            goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("fullReduceActivity"));
            break;
        case "integral":
            goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("integralActivity"));
            break;
        default:
            goodsActivityContext = null;
    }

    return goodsActivityContext;
}

}
复制代码
步骤四.在控制层中调用策略模式

复制代码
@RestController
public class ActivityController{

@Autowired
private GoodsActivityStrategyFactory goodsActivityStrategyFactory;
@RequestMapping("getLastPrice_V2")
public ResponseResult getLastPrice_V2(String activityType,BigDecimal amount){
    ResponseResult responseResult = ResponseResult.getInstance();
    //从工厂中获取  活动策略
    GoodsActivityContext goodsActivityContext = goodsActivityStrategyFactory.getGoodsActivityStrategy(activityType);

    if (goodsActivityContext==null){
        responseResult.setCode(1);
        responseResult.setData(null);
        responseResult.setMsg("数据类型错误");
        return responseResult;
    }

    responseResult.setCode(0);
    responseResult.setMsg("操作成功");
    responseResult.setData(goodsActivityContext.getPrice(amount));

    return responseResult;

}

}
复制代码

源码:

在springboot中使用策略模式

原文地址https://www.cnblogs.com/boychen/p/10721078.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值