您的位置:首页 > 编程语言 > Java开发

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

2019-04-17 00:12 836 查看

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中使用策略模式

 

 

 在工作中,不能灵活的时候设计模式。希望通过这次的学习,可以加深对设计模式对理解。

接下来会继续整理出自己在工作对时候可以使用对设计模式,不对望指点。如果文章对您有帮助,github给个start吧。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: