ifelse像诗一样优雅

注解方式 维护map

map<channelId,实现类> 通过扫描有注解的实现类和实现类上面的注解值维护map,
map<paytype,实现类> 通过获取接口的所有实现类和实现类里面的payType维护map

数据库表
//支付渠道表
渠道Id 渠道名称   折扣

//商品表
商品id   商品名称   商品价格

一。共性接口 和各个银行支付实现类

//接口
public interface Strategy {
    /**
     * @param channelId  通过渠道id拿到折扣
     * @param goodsId    通过商品id拿到价格
     * @return   返回 折扣 * 价格
     */
    BigDecimal calRecharge(Integer channelId,Integer goodsId);

//工商银行支付实现
@Pay(channelId = 1)
public class ICBCBankImpl implements Strategy {
    @Override
    public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
        Channel channel = channelMapper.selectById(channelId);
        Goods goods = goodsMapper.selectById(goodsId);
        if(channel !=null && goods!= null ){
            return goods.getAmout.multiply(channel.getDiscount);
        }
        return null;
    }
}

二。工厂类

功能:1.创建实现类对象 (采用了反射的方法)
2.维护Map 通过注解上的值和所注解的类构成map

public class StrategyFactory {
    //1.创建本类实例
    private static StrategyFactory strategyFactory = new StrategyFactory();

    //2.构造方法私有化private
    private StrategyFactory(){

    }

    //3.对外提供暴露一个获取本类实例的方法
    public static StrategyFactory getInstance(){
        return strategyFactory;
    }
    
    //map   (1,“com.ruoyi.web.controller.pay.impl.ICBCBankImpl”)    
    private static Map<Integer,String> source_map = new HashMap<>();

   //通过注解维护map   注解上写的"channelId = 1" 和 所注解的类构成Map
   static {
          //1.扫描impl包下的所有类
          Reflections reflections =new Reflections("com.ruoyi.web.controller.pay.impl");
          //2.impl包下类上有pay注解的类
          Set<Class<?>> classSet = reflections.getTypeAnnotatedWith(Pay.class);
         //3.循环遍历set 放到map里
         for(Class clazz: classSet){    //遍历实现类
            Pay pay = (Pay) clazz.getAnnotation(Pay.class); //获取实现类上面的注解
            source_map.put(pay.channelId(),clazz.getCanonicalName());
         }
    }

    //4.生产方法:根据上文id生产出某个银行支付实现的类
    public Strategy create(Integer channelId)  throws ClassNotFoundException{{
        String str = source_map.get(channelId);  //str = "com.ruoyi.web.controller.pay.impl.ICBCBankImpl";
        Class clazz = Class.forName(str);
        return (Strategy) clazz.newInstance();
    }
}
//包扫描依赖 Reflections
<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.10</version>
</dependency>

三。上下文类 根据channelId获取实现类

功能: 创建对象并计算价格
——创建对象由工厂类来创建 计算由创建出来的对象来计算

public class Context {
    public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
        StrategyFactory strategyFactory = StrategyFactory.getInstance();
        Strategy strategy = strategyFactory.create(channelId);
        return strategy.calRecharge(channelId, goodsId);
    }
}

四。自定义注解类

功能;维护工厂类的map
步骤:1.添加如下注解类文件
2.实现类上方加上 @Pay(channelId = 1)
3.工厂类通过注解维护map

@Target(ElementType.TYPE)   //指定注解作用在什么上面。 type类  METHOD方法  field成员变量   PARAMETER参数  CONSTRUCTOR构造方法
@Retention(RetentionPolicy.SOURCE)   //指定注解声明周期
public @interface Pay {
    int channelId();  //if什么这里就是什么
}

在这里插入图片描述

策略模式 Spring容器获取实现类维护map

1.共性接口及其实现类

public interface PayService {
    public String pay(Double name);
    public PayType payType();
}

@Service
public class AliPayServiceImpl implements PayService {
    @Override
    public PayType payType(){
        return PayType.AliPay;
    }
    @Override
    public String pay(Double name) {
        System.out.println("支付宝支付。。。。。。。。。。。。。。。。");
        return "AliPay";
    }
}

@Service
public class WechatPayServiceImpl implements PayService {
    @Override
    public PayType payType() {
        return PayType.WeChatPay;
    }

    @Override
    public String pay(Double name) {
        System.out.println("微信支付。。。。。。。。。。。。。。。。");
        return "WeChat";
    }
}

2.上下文类

1.维护map,根据接口的实现类和实现类里面的payType
2.获取对应的实现类

@Component
public class PayServiceUtil implements ApplicationContextAware {

    //1.初始化Spring容器对象
    private ApplicationContext applicationContext;

    //2.获取Springr容器对象
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    //3.声明map
    private Map<PayType, PayService> payServiceMap = new HashMap<PayType, PayService>();


    /**
     * 4.注册所有支付类型(获取所有支付实现类)
     */
    @PostConstruct
    public void registerAllPayService(){
        //payService有几个实现类
        Map<String, PayService> payMap = applicationContext.getBeansOfType(PayService.class);
        for (PayService payService:payMap.values()){
            payServiceMap.put(payService.payType(),payService);
        }
    }

    /**
     * 5.根据支付类型选择实现类  (根据支付渠道id选择实现类)
     * @param payType
     * @return
     */
    public PayService getPayServiceBypayType(PayType payType){
        return payServiceMap.get(payType);
    }
}

3.控制器

@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World!";
    }

    @ResponseBody
    @RequestMapping("/pay")
    public String pay(){
        ApplicationContext context = SpringUtil.context;  //获取Spring容器
        PayServiceUtil payServiceUtil = context.getBean(PayServiceUtil.class);  //获取上下文
        PayService payService1 = payServiceUtil.getPayServiceBypayType(PayType.AliPay);   //获取支付宝支付实现类
        payService1.pay(152.25);

        PayService payService2 = payServiceUtil.getPayServiceBypayType(PayType.WeChatPay);  //获取微信支付实现类
        payService2.pay(152.25);
        return "Hello World222!";
    }
}

4.SpringUtil和PayType

//获取Spring容器对象
@Component
public class SpringUtil extends ApplicationObjectSupport {

    public static ApplicationContext context;
    public static Object getBean(String serviceName){
        return context.getBean(serviceName);
    }
    @Override
    protected void initApplicationContext(ApplicationContext context) throws BeansException {
        super.initApplicationContext(context);
        SpringUtil.context = context;      
    }
}
//枚举类型:支付种类
public enum PayType {
    AliPay,
    WeChatPay,
    CreditPay;
}
发布了172 篇原创文章 · 获赞 0 · 访问量 5705

猜你喜欢

转载自blog.csdn.net/weixin_44635157/article/details/104520913