策略模式
定义:指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
简易UML图
需求分析
每当节假日来临,众多商品就会进行相应折扣,以此来吸引客户,不同的节日,有不同寓意,也就是说,不同的节日,某些商品将赋予特定价值,而这时带来了巨大的需求,市场供求过大。为竞争其他商户,为自家商品迎来订单,这时就需要饥饿效应,玩打折来吸引客户。
可到底是哪些商品进行打折,以及每个商品需要打多少折扣,既保证吸引客户,又能保证赚钱。这就需要为商品分类进行算法得出,同时在业务中,我们很可能要写异常多的类,如果杂糅在一起,那对于维护极不方便。
而策略模式,就是可以将每个单独商品分类价格处理,避免代码的耦合性太高。
具体实现
定义接口
package com.test.strategy;
import com.test.domain.Goods;
/**
* 策略方法
* @author 12134
*
*/
public interface IJRStrategy {
/**
* 活动,每个活动都有特定的商品奖励活动,该商品活动根据算法计算出来
*/
String activity(Goods goods);
}
自定义接口
用于判断该活动属于那个节日。
package com.test.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.test.enums.ActivityJREnum;
/**
* 节日商品注解
* @author 12134
*
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface JRGoodSource {
ActivityJREnum value();
}
定义节日枚举类
package com.test.enums;
public enum ActivityJREnum {
/**
* 七夕节
*/
QIXIJIE(1,"七夕节"),
/**
* 劳动节
*/
LAODONGJIE(2,"劳动节"),
/**
* 元宵节
*/
YUANXIAOJIE(3,"元宵节");
private Integer code;
private String name;
ActivityJREnum() {
}
ActivityJREnum(Integer code, String name) {
this.code = code;
this.name = name;
}
public Integer getCode() {
return code;
}
public String getName() {
return name;
}
}
定义接口实现类
也是算法和业务处理的地方。
package com.test.strategy.impl;
import java.text.DecimalFormat;
import com.test.annotation.JRGoodSource;
import com.test.domain.Goods;
import com.test.enums.ActivityJREnum;
import com.test.strategy.IJRStrategy;
/**
* 劳动节
* @author 12134
*
*/
@JRGoodSource(ActivityJREnum.LAODONGJIE)
public class LaoDongJR implements IJRStrategy{
/**
* 商品的价格打折处理
*/
@Override
public String activity(Goods goods) {
// 劳动节特定商品打七折
DecimalFormat df =new DecimalFormat("#.00");
String result = df.format(goods.getPrice()*0.7);
return result;
}
}
package com.test.strategy.impl;
import java.text.DecimalFormat;
import com.test.annotation.JRGoodSource;
import com.test.domain.Goods;
import com.test.enums.ActivityJREnum;
import com.test.strategy.IJRStrategy;
/**
* 七夕节 情侣专用的商品 算法得出:销量最好的,玫瑰、巧克力、酒店等等商品
*
* @author 12134
*
*/
@JRGoodSource(ActivityJREnum.QIXIJIE)
public class QixiJR implements IJRStrategy {
/**
* 商品的打折处理
* @param price 商品价格
*/
@Override
public String activity(Goods goods) {
// 情人节特定商品打八折
DecimalFormat df =new DecimalFormat("#.00");
String result = df.format(goods.getPrice()*0.8);
return result;
}
}
package com.test.strategy.impl;
import java.text.DecimalFormat;
import com.test.annotation.JRGoodSource;
import com.test.domain.Goods;
import com.test.enums.ActivityJREnum;
import com.test.strategy.IJRStrategy;
/**
* 元宵节
*
* @author 12134
*
*/
@JRGoodSource(ActivityJREnum.YUANXIAOJIE)
public class YuanXiaoJR implements IJRStrategy {
/**
* 商品的打折处理
*/
@Override
public String activity(Goods goods) {
// 元宵节特定商品打九折
DecimalFormat df =new DecimalFormat("#.00");
String result = df.format(goods.getPrice()*0.9);
return result;
}
}
定义pojo
package com.test.domain;
public class Goods {
/**
* 商品编号
*/
private String no;
/**
* 商品名称
*/
private String name;
/**
* 商品价格
*/
private Double price;
/**
* 本次活动名 1:七夕节,2:劳动节,3:元宵节
*/
private Integer sourceFlg;
/**
* 活动折扣和提示信息
*/
private Discount discount;
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Integer getSourceFlg() {
return sourceFlg;
}
public void setSourceFlg(Integer sourceFlg) {
this.sourceFlg = sourceFlg;
}
public Discount getDiscount() {
return discount;
}
public void setDiscount(Discount discount) {
this.discount = discount;
}
public Goods() {
super();
}
public Goods(String no, String name, Double price, Integer sourceFlg) {
super();
this.no = no;
this.name = name;
this.price = price;
this.sourceFlg = sourceFlg;
}
public Goods(String no, String name, Double price, Integer sourceFlg, Discount discount) {
super();
this.no = no;
this.name = name;
this.price = price;
this.sourceFlg = sourceFlg;
this.discount = discount;
}
@Override
public String toString() {
return "Goods [no=" + no + ", name=" + name + ", price=" + price + ", sourceFlg=" + sourceFlg + ", discount="
+ discount + "]";
}
}
package com.test.domain;
import java.io.Serializable;
/**
* 商品折扣
*
* @author 12134
*
*/
public class Discount implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 折扣编号
*/
private int no;
/**
* 折扣信息
*/
private String message;
/**
* 节日提示信息
*/
private String jieRi;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getJieRi() {
return jieRi;
}
public void setJieRi(String jieRi) {
this.jieRi = jieRi;
}
public Discount(int no, String message, String jieRi) {
super();
this.no = no;
this.message = message;
this.jieRi = jieRi;
}
public Discount() {
super();
}
@Override
public String toString() {
return "Discount [no=" + no + ", message=" + message + ", jieRi=" + jieRi + "]";
}
}
package com.test.domain;
import java.io.Serializable;
public class ResponseMessage implements Serializable {
private static final long serialVersionUID = 1L;
private Integer code;
private Object data;
private String msg;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public ResponseMessage(Integer code, Object data, String msg) {
super();
this.code = code;
this.data = data;
this.msg = msg;
}
public ResponseMessage() {
super();
}
@Override
public String toString() {
return "ResponseMessage [code=" + code + ", data=" + data + ", msg=" + msg + "]";
}
}
定义处理接口调用
package com.test.strategy.context;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.test.domain.Goods;
import com.test.strategy.IJRStrategy;
public class JRSimpleContext {
private final Map<Integer, IJRStrategy> strategyMap = new ConcurrentHashMap<>();
/**
* 构造函数
*
* @param strategyMap
*/
public JRSimpleContext(Map<Integer, IJRStrategy> strategyMap) {
this.strategyMap.clear();
strategyMap.forEach((k, v) -> this.strategyMap.put(k, v));
}
/**
* 商品订单编号处理
*
* @param requestId
* @return
*/
public List<Goods> getSource(List<Goods> goodsInfo) {
System.out.println(strategyMap);
for (int i = 0; i < goodsInfo.size(); i++) {
Goods goods2 = goodsInfo.get(i);
// 如果订单商品编号不为空
if (strategyMap.get(goodsInfo.get(i).getSourceFlg()) != null) {
// 获取该活动的价格
String price = strategyMap.get(goodsInfo.get(i).getSourceFlg()).activity(goods2);
goods2.setPrice(Double.valueOf(price));
} else {
System.out.println("你选购的商品不符合本次活动,暂不享受优惠,感谢你的使用!");
}
}
return goodsInfo;
}
}
定义主方法
package com.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import com.test.domain.Discount;
import com.test.domain.Goods;
import com.test.domain.ResponseMessage;
import com.test.enums.ActivityJREnum;
import com.test.strategy.IJRStrategy;
import com.test.strategy.context.JRSimpleContext;
import com.test.strategy.impl.LaoDongJR;
import com.test.strategy.impl.QixiJR;
import com.test.strategy.impl.YuanXiaoJR;
public class Main {
private static JRSimpleContext jrSimpleContext;
public static void main(String[] args) {
List<Goods> goodsInfo = new ArrayList<Goods>();
Goods goods1 = new Goods("1", "玫瑰", 888.0, 1);
Goods goods2 = new Goods("2", "巧克力", 999.0, 1);
Goods goods3 = new Goods("3", "苹果", 999.0, 2);
goodsInfo.add(goods1);
goodsInfo.add(goods2);
goodsInfo.add(goods3);
// 申明折扣
Discount discount = null;
// 申明节日策略
IJRStrategy ijrStrategy = null;
// 创建返回提示内容
StringBuilder sb =new StringBuilder();
ConcurrentHashMap<Integer, IJRStrategy> concurrentHashMap = new ConcurrentHashMap<>();
for (int i = 0; i < goodsInfo.size(); i++) {
Integer sourceFlg = goodsInfo.get(i).getSourceFlg();
if ( ActivityJREnum.QIXIJIE.getCode().equals(sourceFlg)) {
ijrStrategy = new QixiJR();
} else if (ActivityJREnum.LAODONGJIE.getCode().equals(sourceFlg)) {
ijrStrategy = new LaoDongJR();
} else if (ActivityJREnum.YUANXIAOJIE.getCode().equals(sourceFlg)) {
ijrStrategy = new YuanXiaoJR();
} else {
// 不处理
}
concurrentHashMap.put(sourceFlg, ijrStrategy);
// 获取商品折扣信息
if (sourceFlg!=null) {
discount = getDiscount(sourceFlg);
}
// 每个商品对应的折扣
goodsInfo.get(i).setDiscount(discount);
}
jrSimpleContext = new JRSimpleContext(concurrentHashMap);
List<Goods> source = jrSimpleContext.getSource(goodsInfo);
sb.append(source);
ResponseMessage rMessage = new ResponseMessage();
rMessage.setCode(200);
rMessage.setData(sb);
rMessage.setMsg("请求成功!");
System.out.println(rMessage);
}
/**
* 判断属于那个活动
*
* @return
*/
public static Discount getDiscount(Integer sourceFlg) {
Discount discount = new Discount();
// 这里还可以更加仔细的衍生下去,对单独的商品进行对应商品折扣判断
if (ActivityJREnum.QIXIJIE.getCode().equals(sourceFlg)) {
// 返回对应商品的折扣
discount.setNo(8);
discount.setMessage("八折");
discount.setJieRi("七夕节专属情侣商品特供:");
} else if (ActivityJREnum.LAODONGJIE.getCode().equals(sourceFlg)) {
discount.setNo(9);
discount.setMessage("九折");
discount.setJieRi("劳动节专属商务商品特供:");
} else if (ActivityJREnum.LAODONGJIE.getCode().equals(sourceFlg)) {
discount.setNo(7);
discount.setMessage("七折");
discount.setJieRi("元宵节专属家庭商品特供:");
} else {
// 不处理
}
return discount;
}
}
执行结果
ResponseMessage [code=200, data=[Goods [no=1, name=玫瑰, price=710.4, sourceFlg=1, discount=Discount [no=8, message=八折, jieRi=七夕节专属情侣商品特供:]], Goods [no=2, name=巧克力, price=799.2, sourceFlg=1, discount=Discount [no=8, message=八折, jieRi=七夕节专属情侣商品特供:]], Goods [no=3, name=苹果, price=699.3, sourceFlg=2, discount=Discount [no=9, message=九折, jieRi=劳动节专属商务商品特供:]]], msg=请求成功!]