使用 策略模式 解决if判断问题

1.现在有一个需求,根据不同的传参payCode选择不同的支付模式 ,

常见的if判断如下

public String toPayHtml(String payCode){
        if("ALI_PAY".equals(payCode)){
            return "使用支付宝支付....";
        }else if ("WEIXIN_PAY".equals(payCode)){
            return "使用微信支付....";
        }else if ("XIAOMI".equals(payCode)){
            return "使用小米支付....";
        }
        return null;
}

策略模式实现1  

源码链接:https://pan.baidu.com/s/1-RwF4IIKNMzDww4UIJIjkA      提取码:adua

1.定义接口, 定义共同行为方法

public interface PayStrategy {

    //共同方法行为
    String toPayHtml();
}

2.分别定义实现类,支付宝支付,微信支付,小米支付

public class AliPayStrategy implements PayStrategy {

    @Override
    public String toPayHtml() {
        return "调用支付宝接口.....";
    }
}
public class WeiXinPayStrategy implements PayStrategy {

    @Override
    public String toPayHtml() {
        return "调用微信支付....";
    }
}
public class XiaoMiPayStrategy implements PayStrategy {
    @Override
    public String toPayHtml() {
        return "调用小米支付....";
    }
}

3.定义枚举类型,存放所有策略的实现

//策略枚举类,存放所有策略的实现
public enum PayEnumStrategy {
    
    //支付宝支付
    ALI_PAY("com.zhang.strategy.impl.AliPayStrategy"),
    
    //小米支付
    XIAOMI_PAY("com.zhang.strategy.impl.XiaoMiPayStrategy"),
    
    //微信支付
    WECHAT_PAY("com.zhang.strategy.impl.WeiXinPayStrategy");
    
    PayEnumStrategy(String className){
        this.setClassName(className);
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }
    
    //class完整地址
    private String className;
}

4.使用工厂初始化实现策略ben,获取具体策略实现

public class StrategyFactory {

    //使用策略工厂获取具体策略实现
    public static PayStrategy getPayStrategy(String stratrgyType){
        try {
            //获取具体的策略class地址
            String className = PayEnumStrategy.valueOf(stratrgyType).getClassName();
            return  (PayStrategy)Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

5.定义上下文,获取具体实现策略,并执行对应策略

@Component
public class PayContextStrategy {

    public String toPayHtml(String payCode){
        if(StringUtils.isEmpty(payCode)){
            return "payCode不能为空!...";
        }
        PayStrategy payStrategy = StrategyFactory.getPayStrategy(payCode);
        if(payStrategy==null){
            return "没有找到具体策略的实现";
        }
        return payStrategy.toPayHtml();
    }
}

6.测试

@RestController
public class PayControlller {

    @Autowired
    private PayContextStrategy payContextStrategy;

    @GetMapping("/toPayHtml")
    public String toPayHtml(String payCode){
        return payContextStrategy.toPayHtml(payCode);
    }
}

策略模式实现2 -通过数据库管理更优

源码链接:https://pan.baidu.com/s/1M7UM-TW3BDgaJ0EXKtrjCw 
提取码:fhvb

1.定义接口, 定义共同行为方法

public interface PayStrategy {

    //共同方法行为
    String toPayHtml();
}

2.分别定义实现类,支付宝支付,微信支付,小米支付,并注入到Spring容器

@Component
public class AliPayStrategy implements PayStrategy {

    @Override
    public String toPayHtml() {
        return "调用支付宝接口.....";
    }
}
@Component
public class WeiXinPayStrategy implements PayStrategy {

    @Override
    public String toPayHtml() {
        return "调用微信支付....";
    }
}
@Component
public class XiaoMiPayStrategy implements PayStrategy {
    @Override
    public String toPayHtml() {
        return "调用小米支付....";
    }
}

3.数据库存储所有策略实现,后期可配置控制是否开启处理

CREATE TABLE `strategy` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `change_name` varchar(50) DEFAULT NULL COMMENT '名称',
  `change_id` varchar(50) DEFAULT NULL COMMENT 'key_id',
  `change_ben_name` varchar(255) DEFAULT NULL COMMENT '实现类名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

4.编辑策略上下文,获取具体策略

@Component
public class PayContextStrategy {

    @Autowired
    private PayStrategyMapper getPayStrategyMapper;

    public String toPayHtml(String payCode){
        if(StringUtils.isEmpty(payCode)){
            return "payCode不能为空!...";
        }
        //查询数据库获取pay策略实体
        PayStrategyEntity payStrategyEntity = getPayStrategyMapper.getStrategyEntity(payCode);
        if(payStrategyEntity==null){
            return "数据库没有找到具体策略的实现";
        }
        //获取执行策略的类名-首字母小写
        String changeBenName = payStrategyEntity.getChangeBenName();
        if(StringUtils.isEmpty(changeBenName)){
            return "没有找到具体策略的实现";
        }
        //通过spring找到策略ben对象
        PayStrategy payStrategy = SpringUtils.getBean(changeBenName, PayStrategy.class);
        //执行策略
        return payStrategy.toPayHtml();
    }
}

5.Spring上下文获取Spring注入ben对象工具类

//spring上下文中获取ben对象
@Component
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtils.applicationContext == null) {
            SpringUtils.applicationContext = applicationContext;
        }
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

6.实体 和 mapper就不贴了 ,测试

@RestController
public class PayControlller {

    @Autowired
    private PayContextStrategy payContextStrategy;

    @GetMapping("/toPayHtml")
    public String toPayHtml(String payCode){
        return payContextStrategy.toPayHtml(payCode);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章