策略模式

定义:指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

简易UML图

节假日折扣叠加学生折扣JAVA 节假日折扣定价策略_List

需求分析

每当节假日来临,众多商品就会进行相应折扣,以此来吸引客户,不同的节日,有不同寓意,也就是说,不同的节日,某些商品将赋予特定价值,而这时带来了巨大的需求,市场供求过大。为竞争其他商户,为自家商品迎来订单,这时就需要饥饿效应,玩打折来吸引客户。
可到底是哪些商品进行打折,以及每个商品需要打多少折扣,既保证吸引客户,又能保证赚钱。这就需要为商品分类进行算法得出,同时在业务中,我们很可能要写异常多的类,如果杂糅在一起,那对于维护极不方便。
而策略模式,就是可以将每个单独商品分类价格处理,避免代码的耦合性太高。

具体实现

节假日折扣叠加学生折扣JAVA 节假日折扣定价策略_ide_02

定义接口

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=请求成功!]