策略模式
定义:指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
简易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{/*** 商品的价格打折处理*/@Overridepublic 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 商品价格*/@Overridepublic 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 {/*** 商品的打折处理*/@Overridepublic 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;}@Overridepublic 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();}@Overridepublic 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();}@Overridepublic 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=请求成功!]
