前面的文章简单的实现了策略模式。今天进阶一下。
依旧用打折的案例。普通用户八折,会员五折。
话不多说,直接上代码
1.来一个用户类的枚举
public enum UserTypeEnum { USER,MEMBER; }
2.接着来一个注解类
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface PersionType { UserTypeEnum type(); }
3.策略接口
public interface PriceStrategy { Double getPrice(PriceQuery query); }
4.写一个抽象类,用来实现策略接口中的方法,并且将公共的前置判断逻辑放在此抽象类中(此为模板设计模式),并定义好抽象方法calcPrice()让各自的策略类中去实现
public abstract class AbstractPrice implements PriceStrategy { @Override public Double getPrice(PriceQuery query) { query.setType(Optional.ofNullable(query.getType()).orElse(UserTypeEnum.USER)); // do something return calcPrice(query); } public abstract Double calcPrice(PriceQuery query); }
5各自的策略类:User(普通用户),Member(会员),都需要继承公共的模板类AbstractPrice
@PersionType(type = UserTypeEnum.MEMBER) public class Member extends AbstractPrice { @Override public Double calcPrice(PriceQuery query) { return query.getPrice()*0.5; } }
@PersionType(type= UserTypeEnum.USER) public class User extends AbstractPrice { @Override public Double calcPrice(PriceQuery query) { return query.getPrice()*0.8; } }
6.写一个工厂类,所有的策略类将注入到这个类中
public class PriceFactory { private static final PriceFactory PRICE_FACTORY=new PriceFactory(); private final List> priceStrategyList; private PriceFactory(){ Reflections reflections=new Reflections("com.etc.demo.stage.test"); Set > classSet=reflections.getTypesAnnotatedWith(PersionType.class); priceStrategyList=classSet.stream().map(c->(Class extends PriceStrategy>) c).collect(Collectors.toList()); } public PriceStrategy getPriceStrategy (UserTypeEnum userTypeEnum) { for (Class extends PriceStrategy> clazz:priceStrategyList){ PersionType type=clazz.getAnnotation(PersionType.class); if (type.type().equals(userTypeEnum)){ try { return clazz.getDeclaredConstructor().newInstance(); } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { e.printStackTrace(); } } } return null; } public static PriceFactory getInstance(){ return PRICE_FACTORY; } }
7.写一个上下文类,用于获取具体的策略类实例,并执行对应策略类实例的计算方法:
public class PriceContext { public static Double getPrice(PriceQuery query){ PriceStrategy priceStrategy=PriceFactory.getInstance().getPriceStrategy(query.getType()); return priceStrategy.getPrice(query); } }
8.测试
学废了吗?
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)