设计模式之策略模式+工厂模式+模板模式

前面的文章简单的实现了策略模式。今天进阶一下。
依旧用打折的案例。普通用户八折,会员五折。
话不多说,直接上代码
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<Class<? extends PriceStrategy>> priceStrategyList;

    private PriceFactory(){
        Reflections reflections=new Reflections("com.etc.demo.stage.test");
        Set<Class<?>> 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
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值