springboot使用策略模式实现一个基本的促销
- 策略模式
定义了算法族,分别封装起来,让它们之间可以互相替换,
此模式让算法的变化独立于使用算法的客户
源码:https://github.com/youxiu326/sb_promotion.git
- 实体层
一共三个实体,分别为商品实体,促销实体,促销结果实体
商品实体定义了商品的销售价 优惠金额 优惠后金额 数量。。。
促销实体定义了促销类型 名称 参与该促销的商品集合
package com.youxiu326.entity; import java.io.Serializable;
import java.math.BigDecimal; /**
* 商品:
*
* <br>优惠金额 <span color="red">discountAmount</span>
* <br>优惠后价格 -1(默认等于销售金额) <span color="red">finalAmount</span>
* <br>销售价 <span color="red">amount</span>
*
*/
public class Product implements Serializable { private String code; private String name; /**
* 销售价
*/
private BigDecimal amount = BigDecimal.ZERO; /**
* 优惠了多少金额
*/
private BigDecimal discountAmount = BigDecimal.ZERO; /**
* 优惠后金额
*/
private BigDecimal finalAmount = new BigDecimal("-1"); private Integer quantity; public Product(){} public Product(String code, String name, BigDecimal amount, Integer quantity) {
this.code = code;
this.name = name;
this.amount = amount;
this.quantity = quantity;
} public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public BigDecimal getAmount() {
return amount;
} public double getAmountDouble(){
return amount.doubleValue();
} public void setAmount(BigDecimal amount) {
this.amount = amount;
} public Integer getQuantity() {
return quantity;
} public void setQuantity(Integer quantity) {
this.quantity = quantity;
} public BigDecimal getDiscountAmount() {
return discountAmount;
} public void setDiscountAmount(BigDecimal discountAmount) {
this.discountAmount = discountAmount;
} /**
* 优惠后金额(默认等于交易金额)
* @return
*/
public BigDecimal getFinalAmount() {
if(finalAmount.compareTo(new BigDecimal("-1"))==0) {
finalAmount = amount;
}
return finalAmount;
} public void setFinalAmount(BigDecimal finalAmount) {
this.finalAmount = finalAmount;
}
}
Product.java
package com.youxiu326.entity; import java.io.Serializable;
import java.util.List; /**
* 促销实体类
*/
public class Promotion implements Serializable { /**
* <span color="red">促销类型:</span>
* <br>FREEONE 免最低一件
* <br>REBATE 八折
* <br>REDUCE 满100减20
*/
public static enum Type{
FREEONE,REBATE,REDUCE
} private Type type; private String name; /**
* 哪些商品应用促销
*/
private List<Product> products; public Promotion(){}
public Promotion(Type type, String name,List<Product> products) {
this.type = type;
this.name = name;
this.products = products;
} public Type getType() {
return type;
} public void setType(Type type) {
this.type = type;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public List<Product> getProducts() {
return products;
} public void setProducts(List<Product> products) {
this.products = products;
}
}
Promotion.java
package com.youxiu326.entity; import java.io.Serializable; /**
* 促销结果
*/
public class PromotionResult implements Serializable { private String name; private Promotion.Type type; private Object result; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Promotion.Type getType() {
return type;
} public void setType(Promotion.Type type) {
this.type = type;
} public Object getResult() {
return result;
} public void setResult(Object result) {
this.result = result;
}
}
PromotionResult.java
package com.youxiu326.exception; /**
* 自定义异常
*/
public class ServiceException extends Exception { private Exception exception; public ServiceException(String message, Exception exception) {
super(message);
this.exception = exception;
} public ServiceException(String message) {
this(message, null);
} public ServiceException(Exception exception) {
this(null, exception);
} public Exception getException() {
return exception;
} public Exception getRootCause() {
if (exception instanceof ServiceException) {
return ((ServiceException) exception).getRootCause();
}
return exception == null ? this : exception;
} @Override
public String toString() {
if (exception instanceof ServiceException) {
return ((ServiceException) exception).toString();
}
return exception == null ? super.toString() : exception.toString();
}
}
ServiceException.java
- 促销实体类
定义了一个抽象类 PromotionStrategy.java
定义了三个促销策略:
/**
* 满足价格大于等于500
* <br>减免价格最低一件商品促销
*/
@Component
public class FreeOneStrategy extends PromotionStrategy/**
* 满足大于200
* <br>八折促销
*/
@Component
public class RebateStrategy extends PromotionStrategy/**
* 满足满100
* <br>减10促销
*/
@Component
public class ReduceStrategy extends PromotionStrategy
package com.youxiu326.abst; import com.youxiu326.entity.Product;
import com.youxiu326.entity.Promotion;
import com.youxiu326.entity.PromotionResult;
import java.math.BigDecimal;
import java.util.List; /**
* 促销抽象类
* 定义公共方法,让子类继承
* 定义抽象方法,让子类实现
*/
public abstract class PromotionStrategy { public abstract Promotion.Type getType(); /**
* 定义执行促销方法
* @param promotion 促销
* @param products 参加促销的商品集合
* @return
*/
public abstract List<PromotionResult> execute(Promotion promotion, List<Product> products); /*
//加法
BigDecimal result1 = num1.add(num2);
//减法
BigDecimal result2 = num1.subtract(num2);
//乘法
BigDecimal result3 = num1.multiply(num2);
//除法
BigDecimal result5 = num2.divide(num1,20,BigDecimal.ROUND_HALF_UP);
//绝对值
BigDecimal result4 = num3.abs(); 比较大小
结果是: -1:小于; 0 :等于; 1 :大于;
BigDecimal b1 = new BigDecimal("-121454125453.145");
if(b1.compareTo(BigDecimal.ZERO)==-1) {
System.out.println("金额为负数!");
}
*/ //优惠金额 discountAmount
//优惠后价格 -1(默认等于销售金额) finalAmount
//销售价 amount /**
* <span color="red">平摊优惠金额</span>
* @param products
* @param disAmount
*/
protected void sharedAmount(List<Product> products,BigDecimal disAmount){ //计算总金额
double totalAmountTemp = products.stream().mapToDouble(it->(
it.getFinalAmount().multiply(new BigDecimal(it.getQuantity().toString()))).doubleValue()
).sum(); //总金额
BigDecimal totalAmount = new BigDecimal(totalAmountTemp+"");
//已分摊金额
BigDecimal sharedAmount = new BigDecimal("0");; //平摊金额到明细
for(int i=0;i<products.size();i++) {
Product product = products.get(i);
if(i == products.size() - 1) {
//② 如果是最后一件商品 ,将剩余优惠金额计算到这个商品内
//例如:
// 商品001 销售价10 数量1 商品002 销售价20 数量2 商品001,002 总共优惠了5元
// 商品001 已经确定可优惠1元
// 那么最后一个商品002 可以优惠 6-1 5元 product.setDiscountAmount(product.getDiscountAmount().add(disAmount).subtract(sharedAmount));
}else {
//该商品总数量
BigDecimal quantity = new BigDecimal(product.getQuantity().toString()); //① 将总优惠金额 * (该商品销售价/总销售价) 得出该商品所占优惠金额
// 例如:
// 商品001 销售价10 数量1 商品002 销售价20 数量2 商品001,002 总共优惠了5元
// 商品001可优惠金额= 5*(10*1/50) 1元
// 商品002可优惠金额= 5*(20*2/50) 4元 //得出该商品可优惠金额
BigDecimal itemDisAmount = disAmount.multiply(
(product.getAmount().multiply(quantity).divide(totalAmount,2,BigDecimal.ROUND_HALF_UP))
); product.setDiscountAmount(product.getDiscountAmount().add(itemDisAmount)); sharedAmount =sharedAmount.add(itemDisAmount);
}
} // ③计算出 商品优惠后的价格 finalAmount
products.stream().forEach(it->{
BigDecimal quantity = new BigDecimal(it.getQuantity().toString());
it.setFinalAmount(it.getAmount().multiply(quantity).subtract(it.getDiscountAmount()));
});
}
}
package com.youxiu326.strategy; import com.youxiu326.abst.PromotionStrategy;
import com.youxiu326.entity.Product;
import com.youxiu326.entity.Promotion;
import com.youxiu326.entity.PromotionResult;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble; /**
* 满足价格大于等于500
* <br>减免价格最低一件商品促销
*/
@Component
public class FreeOneStrategy extends PromotionStrategy { /**
* 指定促销类型为:FREEONE
* @return
*/
@Override
public Promotion.Type getType() {
return Promotion.Type.FREEONE;
} @Override
public List<PromotionResult> execute(Promotion promotion, List<Product> products) { List<PromotionResult> results = new ArrayList<PromotionResult>(); //计算总金额 总数量
double totalAmount = products.stream().mapToDouble(it->(
(it.getAmount().multiply(new BigDecimal(it.getQuantity().toString())))).subtract(it.getDiscountAmount()).doubleValue()
).sum();
int totalQuantity = products.stream().mapToInt(it->it.getQuantity()).sum(); //TODO 这儿简单处理定死了规则
//不满足促销规则的返回空促销
if (totalAmount<500 || totalQuantity<=1){
return results;
} //获得可优惠金额
double reduceAmount = products.stream().mapToDouble(Product::getAmountDouble).min().orElse(0); //平摊金额
sharedAmount(products, new BigDecimal(reduceAmount+"")); //创建减免促销信息
PromotionResult result = new PromotionResult();
result.setName(promotion.getName());
result.setType(Promotion.Type.FREEONE);
result.setResult(reduceAmount);
results.add(result); return results;
}
}
FreeOneStrategy.java
package com.youxiu326.strategy; import com.youxiu326.abst.PromotionStrategy;
import com.youxiu326.entity.Product;
import com.youxiu326.entity.Promotion;
import com.youxiu326.entity.PromotionResult;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List; /**
* 满足大于200
* <br>八折促销
*/
@Component
public class RebateStrategy extends PromotionStrategy { /**
* 指定促销类型为:REBATE
* @return
*/
@Override
public Promotion.Type getType() {
return Promotion.Type.REBATE;
} @Override
public List<PromotionResult> execute(Promotion promotion, List<Product> products) { List<PromotionResult> results = new ArrayList<PromotionResult>(); //计算总金额 总数量
double totalAmount = products.stream().mapToDouble(it->(
(it.getAmount().multiply(new BigDecimal(it.getQuantity().toString())))).subtract(it.getDiscountAmount()).doubleValue()
).sum();
int totalQuantity = products.stream().mapToInt(it->it.getQuantity()).sum(); //TODO 这儿简单处理定死了规则
//不满足促销规则的返回空促销
if (totalAmount<200){
return results;
} //获得可优惠金额
double reduceAmount = totalAmount * 0.2; //平摊金额
sharedAmount(products, new BigDecimal(reduceAmount+"")); //创建减免促销信息
PromotionResult result = new PromotionResult();
result.setName(promotion.getName());
result.setType(Promotion.Type.REBATE);
result.setResult(reduceAmount);
results.add(result); return results;
} }
RebateStrategy.java
package com.youxiu326.strategy; import com.youxiu326.abst.PromotionStrategy;
import com.youxiu326.entity.Product;
import com.youxiu326.entity.Promotion;
import com.youxiu326.entity.PromotionResult;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List; /**
* 满足满100
* <br>减10促销
*/
@Component
public class ReduceStrategy extends PromotionStrategy { /**
* 指定促销类型为:REDUCE
* @return
*/
@Override
public Promotion.Type getType() {
return Promotion.Type.REDUCE;
} @Override
public List<PromotionResult> execute(Promotion promotion, List<Product> products) { List<PromotionResult> results = new ArrayList<>(); //计算总金额 总数量
double totalAmount = products.stream().mapToDouble(it->(
(it.getAmount().multiply(new BigDecimal(it.getQuantity().toString())))).subtract(it.getDiscountAmount()).doubleValue()
).sum();
int totalQuantity = products.stream().mapToInt(it->it.getQuantity()).sum(); //TODO 这儿简单处理定死了规则
//不满足促销规则的返回空促销
if (totalAmount<100){
return results;
} //获得可优惠金额
double reduceAmount = 10; //平摊金额
sharedAmount(products, new BigDecimal(reduceAmount+"")); //创建减免促销信息
PromotionResult result = new PromotionResult();
result.setName(promotion.getName());
result.setType(Promotion.Type.REDUCE);
result.setResult(reduceAmount);
results.add(result); return results;
} }
ReduceStrategy.java
package com.youxiu326.context; import com.youxiu326.abst.PromotionStrategy;
import com.youxiu326.entity.Product;
import com.youxiu326.entity.Promotion;
import com.youxiu326.entity.PromotionResult;
import com.youxiu326.exception.ServiceException;
import java.util.Collection;
import java.util.List; /**
* 促销上下文
*/
public class PromotionContext { /**
* 促销策略
*/
private PromotionStrategy strategy; /**
* 当前促销
*/
private Promotion promotion; public static Collection<PromotionStrategy> strategys; public PromotionContext(){} public PromotionContext(Promotion promotion) throws ServiceException { this.promotion = promotion;
//初始化促销列表
if(strategys == null)throw new ServiceException("无可用促销"); //根据传入的促销 找到对应的促销策略 【strategy】
strategy = strategys.stream().filter(it->it.getType() == promotion.getType()).findFirst().orElse(null); if(strategy == null) throw new ServiceException("找不到符合促销类型");
} public List<PromotionResult> execute(List<Product> products) throws ServiceException{
return strategy.execute(promotion, products);
} public Collection<PromotionStrategy> getStrategys() {
return strategys;
} public void setStrategys(Collection<PromotionStrategy> strategys) {
PromotionContext.strategys = strategys;
}
}
- 促销service
处理促销业务逻辑
package com.youxiu326.service; import com.youxiu326.entity.Product;
import com.youxiu326.entity.Promotion;
import com.youxiu326.entity.PromotionResult;
import com.youxiu326.exception.ServiceException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map; public interface PromotionService { /**
* <span color="red">结算方法</span>
* <br>结算对象包含:
* <br>1.商品优惠价格
* <br>2.优惠后最终价格
* <br>3.优惠信息
* @param products 要结算的商品集合
* @return Object 返回结算后的对象
*/
public Map<String,Object> settlement(List<Product> products) throws ServiceException; /**
* 查询可用的促销
* @return
*/
public List<Promotion> findUsablePromotions(); /**
* 过滤出可以参加指定促销的商品
* @param promotion 指定促销
* @param products 要过滤的商品集合
* @return 返回过滤后的商品集合
*/
public List<Product> filterProduct(Promotion promotion, List<Product> products); /**
* 执行促销
* @param promotions 促销集合
* @param products 商品集合
* @return
*/
public List<PromotionResult> execute(List<Promotion> promotions, List<Product> products) throws ServiceException; }
package com.youxiu326.service.impl; import com.youxiu326.abst.PromotionStrategy;
import com.youxiu326.context.PromotionContext;
import com.youxiu326.entity.Product;
import com.youxiu326.entity.Promotion;
import com.youxiu326.entity.PromotionResult;
import com.youxiu326.exception.ServiceException;
import com.youxiu326.service.PromotionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* 促销service
*/
@Service
public class PromotionServiceImpl implements PromotionService { private static final Logger LOGGER = LoggerFactory.getLogger(PromotionServiceImpl.class); //@Autowired
//private ContextStartup contextStartup; @Autowired
private ApplicationContext application; /**
* 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,
* <br>类似于Serclet的inti()方法
* <br>被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行
*/
@PostConstruct
public void init() {
PromotionContext.strategys = application.getBeansOfType(PromotionStrategy.class).values();
} @Override
public Map<String,Object> settlement(List<Product> products) throws ServiceException{ Map<String,Object> resultMap = new HashMap<>(); //查询可用促销
List<Promotion> promotions = findUsablePromotions();
//执行促销
List<PromotionResult> result = execute(promotions,products); //返回促销结果 与商品
resultMap.put("promotionResult", result);
resultMap.put("products", products);
return resultMap;
} /**
* 执行促销
* @param promotions 促销集合
* @param products 商品集合
* @return
*/
@Override
public List<PromotionResult> execute(List<Promotion> promotions, List<Product> products) throws ServiceException {
LOGGER.info("促销开始执行 促销数量:{} 商品数量:{}",promotions.size(),products.size()); products.stream().forEach(it->LOGGER.info("执行促销商品信息->编号:{} 价格:{} 数量:{}",it.getCode(),it.getAmount(),it.getQuantity())); //返回促销结果
List<PromotionResult> promotionResults = new ArrayList<PromotionResult>(); //遍历执行促销
for (Promotion promotion : promotions) { //根据传入的促销 得到对应的促销上下文
PromotionContext context = new PromotionContext(promotion); //过滤出可以参加该促销的商品
List<Product> filterProductList = filterProduct(promotion, products); //根据策略模式 执行先对应的促销规则,返回促销结果
List<PromotionResult> result = context.execute(filterProductList);
if (result!=null){
promotionResults.addAll(result);
} } //TODO 如果有的促销参加多次,应该要进行一定处理,只取一个即可 LOGGER.info("促销执行结束");
return promotionResults;
} /**
* 查询可用的促销
* @return
*/
@Override
public List<Promotion> findUsablePromotions(){
//TODO 这儿你可以直接查询数据库 List<Promotion> promotions = new ArrayList<>();
Promotion p1 = new Promotion(Promotion.Type.FREEONE,"价格大于等于500免最低一件",null);
Promotion p2 = new Promotion(Promotion.Type.REBATE,"大于200八折",null);
Promotion p3 = new Promotion(Promotion.Type.REDUCE,"满100减10",null);
promotions.add(p1);
promotions.add(p2);
promotions.add(p3);
LOGGER.info("查询到可用促销数量:{}",promotions.size());
return promotions;
} /**
* 过滤出可以参加指定促销的商品
* @param promotion 指定促销
* @param products 要过滤的商品集合
* @return 返回过滤后的商品集合
*/
@Override
public List<Product> filterProduct(Promotion promotion, List<Product> products){
List<Product> list = new ArrayList<Product>(); products.stream().forEach(it->{
if (isMatching(promotion, it)) {
list.add(it);
}
}); return list;
} /**
* 判断该商品是否可以参加该促销
* @param promotion
* @param product
* @return
*/
private boolean isMatching(Promotion promotion, Product product) {
//TODO 这里你应该查询数据库 1.看满足该促销的商品中是否包含该商品,2.如果该促销未设置商品默认所有商品都满足 List<Product> products = null; //没有 所以商品都满足参加该促销的要求 返回true
if(products == null || products.size() == 0)return true; //如果该商品在该促销商品集合内 则返回true 否则返回false
long count = products.stream().filter(it->it.getCode().equals(product.getCode())).count(); return count>0?true:false;
} }
- Junit
package com.youxiu326; import com.youxiu326.entity.Product;
import com.youxiu326.exception.ServiceException;
import com.youxiu326.service.PromotionService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; @RunWith(SpringRunner.class)
@SpringBootTest
public class SbPromotionApplicationTests { @Autowired
PromotionService service; @Test
public void contextLoads() throws ServiceException { List<Product> products = new ArrayList<>(); Product p1 = new Product("YX001", "牙刷", new BigDecimal("50"), 2);
Product p2 = new Product("YX002", "电视", new BigDecimal("200"), 2);
Product p3 = new Product("YX003", "圆珠笔", new BigDecimal("20"), 2);
Product p4 = new Product("YX004", "水杯", new BigDecimal("60"), 1);
Product p5 = new Product("YX005", "充电宝", new BigDecimal("400"), 1);
/*products.add(p1);
products.add(p2);
products.add(p3);
products.add(p4);*/
products.add(p5); Map<String, Object> result = service.settlement(products); System.out.println(result); } }
- 为了方便 写了一个简易页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="${#httpServletRequest.getContextPath()+'/'}">
<meta charset="UTF-8">
<title>springboot+策略模式 实现简单促销</title>
</head>
<body>
<h2>提交商品</h2> <body> <table>
<tr>
<td>商品名称</td>
<td>商品价格</td>
<td>商品数量</td>
<td>操作</td>
</tr>
<tr>
<td><input id="name" /></td>
<td><input id="amount" type="number" /></td>
<td><input id="quantity" type="number" /></td>
<td><input type="button" value="添加该商品" onclick="data()"/></td>
</tr>
</table> <h6>购物车商品</h6>
<div width="400px" height="400px" id="showShoop"></div> <br>
<input type="button" onclick="sub()" value="将这些商品进行促销"/>
<br> <h6>参加促销信息展示</h6>
<div width="400px" height="400px" id="showPro"></div> <h6>已添加商品信息展示</h6>
<table>
<tr>
<td>商品编号</td>
<td>商品名称</td>
<td>商品数量</td>
<td>优惠后总价</td>
<td>总优惠金额</td>
</tr>
<tbody id="showTab"></tbody>
</table> </body> <script src="/jquery-1.11.3.min.js"></script>
<script> var products = [];
var num = 1;
<!-- 准备数据 -->
function data(){
var name = $("#name").val();
var amount = $("#amount").val();
var quantity = $("#quantity").val();
if(name=="" || amount=="" || quantity=="" || name==undefined || amount==undefined || quantity==undefined ){
alert("商品格式有误");
return ;
}
var code = "youxiu-"+ num;
num=num+1;
var product = {"code":code,"name":name,"amount":amount,"quantity":quantity};
products.push(product);
console.log(products); var em = "<span>"+product.name+"--"+product.quantity+"--"+product.amount+"</span><br>";
$("#showShoop").append(em);
} function sub(){
if(products.length<=0){
alert("请添加商品");
retur;
}
$.ajax({
type: 'POST',
url: "/data",
data: JSON.stringify(products),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(map){
if(map==null){
alert("出错了");
}
var promotionResult = map.promotionResult;
var result = map.products;
console.log("促销结果:");
console.log(promotionResult);
console.log();
console.log("促销后商品信息:");
console.log(result); //促销信息展示
$("#showPro").empty();
for(var i=0;i<promotionResult.length;i++){
var em = "<span>"+promotionResult[i].name+"------"+promotionResult[i].result+"</span><br>";
$("#showPro").append(em);
} //促销商品展示
$("#showTab").empty();
for(var i=0;i<result.length;i++){
var em = "<tr><td>"+result[i].code+"</td><td>"+result[i].name+"</td><td>"+result[i].quantity+"</td><td>"+result[i].finalAmount+"</td><td>"+result[i].discountAmount+"</td></tr>";
$("#showTab").append(em);
}
},
error:function(map){
alert(map);
console.log(map);
}
});
} </script> </html>
package com.youxiu326.controller; import com.youxiu326.entity.Product;
import com.youxiu326.exception.ServiceException;
import com.youxiu326.service.PromotionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import java.util.List;
import java.util.Map; /**
* 促销controller
*/
@Controller
public class PromotionCtrl { @Autowired
private PromotionService service; @GetMapping("/index")
public String index(){
return "/index";
} @PostMapping("/data")
@ResponseBody
public Map data(@RequestBody List<Product> products){
Map map = null;
try {
map = service.settlement(products);
} catch (ServiceException e) {
return null;
}
return map;
} }
演示地址:http://promotion.youxiu326.xin
源码:https://github.com/youxiu326/sb_promotion.git
springboot使用策略模式实现一个基本的促销的更多相关文章
- SpringBoot结合策略模式实战套路
1. SpringBoot结合策略模式实战套路 1.1. 前言 我们都知道设计模式好,可以让我们的代码更具可读性,扩展性,易于维护,但大部分程序猿一开始都学过至少一遍设计模式吧,实战中不知用到了几成. ...
- ## springboot 下策略模式的简单使用
1.灵魂三问 接手前人(已跑路)项目快乐否? 前人项目不写注释懵逼否? 一个方法中一堆if/else,且业务判断条件用简单数字(或英文字母),不带注释,想打人否? 所以,对于上述三个问题,我写 ...
- 用SpringBoot实现策略模式
问题的提出 阅读别人代码的时候最讨厌遇到的就是大段大段的if-else分支语句,一般来说读到下面的时候就忘了上面在判断什么了.很多资料上都会讲到使用策略模式来改进这种代码逻辑. 策略模式的类图如下: ...
- SpringBoot使用策略模式+工厂模式
为了防止大量的if...else...或switch case代码的出现,可以使用策略模式+工厂模式进行优化. 在我的项目当中,报表繁多,所以尝试了这种方式进行优化报表的架构.代码很简单,如下: Fa ...
- 基于Spring实现策略模式
背景: 看多很多策略模式,总结下来实现原理大体都差不多,在这里主要是讲解下自己基于Spring更优雅的实现方案:这个方案主要是看了一些开源rpc和Spring相关源码后的一些思路,所以在此进行总结 首 ...
- 设计模式-策略模式(Strategy Model)
1.概述 在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能. 如在人物比较排序的实现中,我们有 ...
- IOS之Objective-C学习 策略模式
对于策略模式,我个人理解策略模式就是对各种规则的一种封装的方法,而不仅仅是对算法的封装与调用而已.与工厂模式中简单工厂有点类似,但是比简单工厂更有耦合度,因为策略模式以相同的方法调用所有的规则,减少了 ...
- Java设计模式6:策略模式
策略模式 策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包 ...
- 【2016-10-14】【坚持学习】【Day5】【策略模式】
今天学了策略模式 例子 一个售票系统,针对不同的用户使用不用的计价方式, 环境类:一个业务场景(电影票累,) 抽象类:计价算法 具体实现类:5折算法,满100减20算法,..... 抽象策略类 abs ...
随机推荐
- Java处理.tif或.tiff图片
前言 Java将图片读取到内存用的是ImageIO,默认可以处理的图片格式如下: ImageIO.getWriterFileSuffixes() //此方法返回可以处理的图片格式数组 jpg bmp ...
- windows 常用的shell(cmd.exe)命令大全
Windows常用shell命令大全(转) [Windows常用shell命令大全] 基于鼠标操作的后果就是OS界面外观发生改变, 就得多花学习成本.更主要的是基于界面引导Path与命令行直达速度是难 ...
- Mono创始人 Miguel de Icaza今天离开微软
2016年,微软突然宣布收购移动工具开发商Xamarin,后者是位于美国加利福尼亚,据称微软收购Xamarin交易价格在4亿到5亿美元之间.因此,微软获得了著名的开源倡导者和开发人员Miguel de ...
- Excel:获取等差时间
假设:从0:01:05开始,每隔1分30秒生成一个时间项 做法: 在A2处写 =TIME( 0,1,5 )构建一个TIME类型0:01:05,如果要构建别的时间,就按照TIME( 时 , 分 , 秒 ...
- docker入门-Dockerfile入门
1.dockerfile 构建基础命令 2. 构建镜像命令 Usage: docker image build [OPTIONS] PATH | URL | -Options:-t, --tag li ...
- 让Node.js支持ES6的语法
使用命令,全局安装es-checker: cnpm install -g es-checker 安装好之后,执行以下命令来查看Node.js对ES6的支持情况. es-checker 可以从输出中查看 ...
- php 23种设计模型 - 装饰模式
装饰器模式(Decorator) 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. ...
- 被广泛使用的OAuth2.0的密码模式已经废了,放弃吧
最近一直有同学在问,OAuth2密码模式为啥Spring Security还没有实现,就连新的Spring Authorization Server也没有这个玩意儿. 其实这里可以告诉大家,OAuth ...
- Nginx解决跨域问题No 'Access-Control-Allow-Origin'
使用nginx在server块下的location块下为请求添加请求头来解决跨域 add_header 'Access-Control-Allow-Origin' '*'; add_header 'A ...
- 2.7 C++STL list容器详解
文章目录 2.7.1 引入 2.7.2代码示例 2.7.3代码运行结果 总结 2.7.1 引入 STL list 容器,又称双向链表容器,即该容器的底层是以双向链表的形式实现的.这意味着,list 容 ...