1.核心工厂类
public class CalPriceFactory {
private static final String CAL_PRICE_PACKAGE = "org.landy.strategy.demo2.calc";
private ClassLoader classLoader = getClass().getClassLoader();
private List<Class<? extends CalPrice>> calPriceList;
public CalPrice createCalPrice(Player player) {
for (Class<? extends CalPrice> clazz : calPriceList) {
PriceRegion validRegion = handleAnnotation(clazz);
if (player.getTotalAmount() > validRegion.min() && player.getTotalAmount() < validRegion.max()) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException("策略获得失败");
}
}
}
throw new RuntimeException("策略获得失败");
}
private PriceRegion handleAnnotation(Class<? extends CalPrice> clazz) {
Annotation[] annotations = clazz.getDeclaredAnnotations();
if (annotations == null || annotations.length == 0) {
return null;
}
for (int i = 0; i < annotations.length; i++) {
if (annotations[i] instanceof PriceRegion) {
return (PriceRegion) annotations[i];
}
}
return null;
}
private CalPriceFactory() {
init();
}
private void init() {
calPriceList = new ArrayList<>();
File[] resources = getResources();
Class<CalPrice> calPriceClazz = null;
try {
calPriceClazz = (Class<CalPrice>) classLoader.loadClass(CalPrice.class.getName());
} catch (ClassNotFoundException e1) {
throw new RuntimeException("未找到策略接口");
}
for (int i = 0; i < resources.length; i++) {
try {
Class<?> clazz = classLoader.loadClass(CAL_PRICE_PACKAGE + "." + resources[i].getName().replace(".class", ""));
if (CalPrice.class.isAssignableFrom(clazz) && clazz != calPriceClazz) {
calPriceList.add((Class<? extends CalPrice>) clazz);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
private File[] getResources() {
try {
File file = new File(classLoader.getResource(CAL_PRICE_PACKAGE.replace(".", "/")).toURI());
return file.listFiles(new FileFilter() {
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".class")) {
return true;
}
return false;
}
});
} catch (URISyntaxException e) {
throw new RuntimeException("未找到策略资源");
}
}
public static CalPriceFactory getInstance() {
return CalPriceFactoryInstance.instance;
}
private static class CalPriceFactoryInstance {
private static CalPriceFactory instance = new CalPriceFactory();
}
}
2.注解类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PriceRegion {
int max() default Integer.MAX_VALUE;
int min() default Integer.MIN_VALUE;
}
3.策略接口及实现类
public interface CalPrice {
Double calPrice(Double originPrice);
}
@PriceRegion(min=3000)
public class GoldVip implements CalPrice {
@Override
public Double calPrice(Double originPrice) {
return originPrice * 0.7;
}
}
@PriceRegion(max = 10000)
public class Origin implements CalPrice {
@Override
public Double calPrice(Double originPrice) {
return originPrice;
}
}
@PriceRegion(min=20000,max=30000)
public class SuperVip implements CalPrice {
@Override
public Double calPrice(Double originPrice) {
return originPrice * 0.8;
}
}
@PriceRegion(max=20000)
public class Vip implements CalPrice {
@Override
public Double calPrice(Double originPrice) {
return originPrice * 0.9;
}
}
4.消费者及策略类
public class Player {
private Double totalAmount = 0D;
private Double amount = 0D;
private CalPrice calPrice = new Origin();
public void buy(Double amount) {
this.amount = amount;
totalAmount += amount;
calPrice = CalPriceFactory.getInstance().createCalPrice(this);
}
public Double calLastAmount() {
return calPrice.calPrice(amount);
}
public Double getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Double totalAmount) {
this.totalAmount = totalAmount;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
}
public class Client {
public static void main(String[] args) {
Player player = new Player();
player.buy(5000D);
System.out.println("玩家需要付钱:" + player.calLastAmount());
player.buy(12000D);
System.out.println("玩家需要付钱:" + player.calLastAmount());
player.buy(20000D);
System.out.println("玩家需要付钱:" + player.calLastAmount());
player.buy(40000D);
System.out.println("玩家需要付钱:" + player.calLastAmount());
}
}