在我看来:
······策略模式的优点是:拓展方便+不影响原有代码+可以提取公共方法,减少代码冗余
······将反射放进策略模式的优点是:可以自动创建对象,不用手动创建
······将枚举放进策略模式的优点是:枚举可以存储多个属性值
本方案拓展的用法:
······只用增加策略的实现类,和枚举类
下面是代码,多看注释,都在注释里
代码大概实现的功能是,2个不同的会员实现不同的折扣
首先是会员的枚举类
public enum UserPlayServiceEnum {
//会员类型,会员实现类名(此名称必须和class名相同),会员折扣
VIP(1, "VipPayService", 0.8),
VVIP(2, "VvipPayService", 0.7);
private int code;//会员类型
private String value;//会员实现类名(此名称必须和class名相同)
private double rebate;//会员折扣
private UserPlayServiceEnum(int code, String value, double rebate) {
this.code = code;
this.value = value;
this.rebate = rebate;
}
//更具传进来的会员类型,返回该会员枚举类型,后面会用到这个类型里面的值
public static UserPlayServiceEnum value(int code) {
for(UserPlayServiceEnum type : UserPlayServiceEnum.values()) {
if (type.getCode() == code) {
return type;
}
}
return null;
}
public double getCode() {
return code;
}
public String getValue() {
return value;
}
public double getRebate() {
return rebate;
}
}
所有会员的父类接口
public interface IUserPayService {
/**
*
* @Title:
* @Description:
* @author:
* @date 2020年6月25日 下午11:41:57
* @param orderPrice 输入的价格
* @param userPlayServiceEnum 会员类型
* @return double 打折后的价格
* @version
*/
public double quote(Double orderPrice,
UserPlayServiceEnum userPlayServiceEnum);
}
2个实现类(实现方法的策略类)
public class VipPayService implements IUserPayService {
@Override
public double quote(Double orderPrice,
UserPlayServiceEnum userPlayServiceEnum) {
System.out.println("Vip打7折");
return userPlayServiceEnum.getRebate()*orderPrice;
}
}
public class VvipPayService implements IUserPayService {
@Override
public double quote(Double orderPrice,
UserPlayServiceEnum userPlayServiceEnum) {
System.out.println("Vvip打6折");
return userPlayServiceEnum.getRebate()*orderPrice;
}
}
策略模式的核心类,此处通过反射new具体对象(这是亮点)
import java.math.BigDecimal;
public class Context {
/**
*
* @Title: getPrice
* @Description: 策略模式的核心,提取了公共代码
* @author: anthor
* @date 2020年6月25日 下午11:44:06
* @param price 输入的价格
* @param code 会员类型代码
* @return double 打折后的价格
* @version
*/
public double getPrice(Double price, int code) {
Class<?> c;
IUserPayService userPayService;
double f1 = 0.00;
try {
//通过反射获取对象,拼接反射对象的包名+反射对象的名字
c = Class.forName("factoryCombinedPolicy.test." +
UserPlayServiceEnum.value(code).getValue());
//new一个Object对象,并且强转成各个会员的接口类
userPayService = (IUserPayService) c.newInstance();
//获取打折后的价格
double f = userPayService.quote(price,
UserPlayServiceEnum.value(code));
BigDecimal b = new BigDecimal(f);
//四舍五入2位小数点,并转换成double类型
f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return f1;
}
}
测试类
public class Test {
public static void main(String[] args) {
//创建策略模式的核心类
Context context = new Context();
//传入价格+会员类型
double d1 = context.getPrice(100.12, 1);
System.out.println(d1);
double d2 = context.getPrice(100.12, 2);
System.out.println(d2);
}
}
控制台输出
Vip打7折
70.08
Vvip打6折
60.07