策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。
UML:
//工厂方法,用来生产策略
public class DisCountRateFactory {
private static final List<String> STRATEGY_LIST;// 策略列表
private static final List<Class<? extends Discount>> STRATEGY_CLASS_LIST;// 策略列表
private static final DisCountRateFactory FACTORY;
static {
FACTORY = new DisCountRateFactory();
STRATEGY_LIST = new ArrayList<String>();
STRATEGY_CLASS_LIST = new ArrayList<Class<? extends Discount>>();
STRATEGY_LIST.add("discount.Common");
STRATEGY_LIST.add("discount.GoldVip");
STRATEGY_LIST.add("discount.BronzeVip");
STRATEGY_LIST.add("discount.SilverVip");
}
@SuppressWarnings("unchecked")
private void getClassByclsName() throws Exception {
for (String strategy : STRATEGY_LIST) {
Class<? extends Discount> cls = (Class<? extends Discount>) Class.forName(strategy);
STRATEGY_CLASS_LIST.add(cls);
}
}
/**
* 获取工厂实例
*
* @return
*/
public static DisCountRateFactory getInstance() {
return FACTORY;
}
// 返回类的注解
private PriceRange handleAnnotation(Class<? extends Discount> clazz) {
Annotation[] annotations = clazz.getDeclaredAnnotations();
if (annotations == null || annotations.length == 0) {
return null;
}
return (PriceRange) annotations[0];
}
public Discount returnDisCountByAonnotation(double money) {
try {
// 获取所有的class
getClassByclsName();
for (Class<? extends Discount> clazz : STRATEGY_CLASS_LIST) {
// 获取该策略的注解
PriceRange range = handleAnnotation(clazz);
// 区间判断
if (money > range.min() && money <= range.max()) {
return clazz.newInstance();
}
}
throw new RuntimeException();
} catch (Exception e1) {
throw new RuntimeException("get strategy failed!");
}
}
}
//策略选择
public class StrategySelector {
private double money;
private Discount disCount = new Common();
public void buy() {
Discount disCountRate = DisCountRateFactory.getInstance()
.returnDisCountByAonnotation(money);
if (disCountRate != null)
disCount = disCountRate;
disCount.disCount(money);
// if (money > 1000 && money <= 2000) {
// disCount = new BronzeVip();
// } else if (money > 2000 && money <= 3000) {
// disCount = new SilverVip();
// } else if (money > 3000) {
// disCount = new GoldVip();
// }
// disCount.disCount(money);
}
public void setMoney(double money) {
this.money = money;
buy();
}
//策略定义
public interface Discount {
void disCount(double price);
}
//其中一个实现
@PriceRange(max = 1000)
public class Common implements Discount {
@Override
public void disCount(double price) {
System.out.println("原价:" + price + ",折扣:" + 0 + ",不享受vip优惠,应付:" + price);
}
}
//test
StrategySelector s = new StrategySelector();
s.setMoney(1000);
System.out.println("-------------");
s.setMoney(2000);
System.out.println("-------------");
s.setMoney(3000);
System.out.println("-------------");
s.setMoney(4000);
System.out.println("-------------");
s.setMoney(5000);
//console:
原价:1000.0,折扣:0,不享受vip优惠,应付:1000.0
-------------
原价:2000.0,折扣:0.9,享受青铜vip优惠,应付:1800.0
-------------
原价:3000.0,折扣:0.8,享受白银vip优惠,应付:2400.0
-------------
原价:4000.0,折扣:0.7,享受黄金vip优惠,应付:2800.0
-------------
原价:5000.0,折扣:0.7,享受黄金vip优惠,应付:3500.0