ifelse like poetry as elegant

Annotations way to maintain map

map <channelId, implementation class> annotated by scanning and implementation classes achieve the above comments maintenance value map,
map <paytype, implementation class> map maintained by acquiring all implementations of interfaces and implementation classes inside payType

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

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

One. Common interfaces and implementation classes each bank payments

//接口
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;
    }
}

two. Factory class

Function: 1. Create an object implementation class (using the reflection method)
2. Map configured to maintain a value in the annotations and the annotated map class

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>

three. Obtaining context class implementation classes channelId

Function: Create object and calculate the price
- create an object factory class to create objects that are created by the calculation to calculate out

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

four. Custom annotation class

Function; maintenance factory class map
: 1 add the following annotation class file.
2. implemented plus the above class @Pay (channelId is = 1)
3. factory class map maintained by the annotation

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

Here Insert Picture Description

Spring acquisition strategy pattern implementation class vessel maintenance map

1. The common interface and its implementation class

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. context class

1. maintenance map, depending on the implementation of the class interface and implementation class inside payType
2. acquired corresponding implementation classes

@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

@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;
}
Published 172 original articles · won praise 0 · Views 5705

Guess you like

Origin blog.csdn.net/weixin_44635157/article/details/104520913