首页 > 其他 > 详细

使用策略模式解决多重判断if-else问题

时间:2020-09-09 11:03:04      阅读:77      评论:0      收藏:0      [点我收藏+]

前言

  也许我们的代码中遇到过多重判断if-else语句,但是这样的代码可读性差,并且当扩展时,违反了“开闭原则”。阿里开发规范中提到的解决方法有:卫语句,策略模式,状态模式。本文讲述的是通过策略模式来解决多重判断if-else语句问题。

正文

  一、多重判断if-else代码

  我们通过支付接口的例子来讲述。代码如下:

  1、Controller层

@RestController
public class PayController {

    @Autowired
    private PayService payService;

    @RequestMapping("/pay")
    public String pay(String type, String amount){
        return payService.pay(type, amount);
    }
}

  2、Service层

public interface PayService {

    /**
     * 支付接口
     * @param type 支付类型
     * @param amount 支付金额
     * @return
     */
    String pay(String type, String amount);
}


@Service
public class PayServiceImpl implements PayService{

    private static String MSG = "使用 %s ,消费了 %s 元";

    @Override
    public String pay(String type, String amount) {
        if (PayEnum.ALI_PAY.getType().equals(type)){
            // 支付宝支付
            return String.format(MSG, PayEnum.ALI_PAY.getDescription(), amount);
        } else if (PayEnum.WECHAT_PAY.getType().equals(type)) {
            // 微信支付
            return String.format(MSG, PayEnum.WECHAT_PAY.getDescription(), amount);
        } else if (PayEnum.UNION_PAY.getType().equals(type)) {
            // 银联支付
            return String.format(MSG, PayEnum.UNION_PAY.getDescription(), amount);
        }
        return "输入的支付类型错误!";
    }
}

  3、Enum枚举类

public enum  PayEnum {

    ALI_PAY("ali", "支付宝支付"),
    WECHAT_PAY("wechat", "微信支付"),
    UNION_PAY("union", "银联支付");

    private String type;

    private String description;

    PayEnum(String type, String description) {
        this.type = type;
        this.description = description;
    }

    public String getType() {
        return type;
    }

    public String getDescription() {
        return description;
    }
}

  当需要增加一个信用卡支付时,需要修改原来的代码,这样就违法了“开闭原则”。

 

  二、策略模式代码

  主要是Service层代码有所改变。

  1、Service层

public interface PayService {

    /**
     * 支付接口
     * @param type 支付类型
     * @param amount 支付金额
     * @return
     */
    String pay(String type, String amount);
}


@Service
public class PayServiceImpl implements PayService{

    private static String MSG = "使用 %s ,消费了 %s 元";

    @Override
    public String pay(String type, String amount) {

        PayStrategy payStrategy = PayStrategyFactory.getPayStrategy(type);
        if (payStrategy == null){
            return "输入的支付类型错误!";
        }
        return payStrategy.pay(type, amount);
    }
}

  2、对多重判断if-else语句的改造

public interface PayStrategy {

    String MSG = "使用 %s ,消费了 %s 元";

    String pay(String type, String amount);
}


@Component("aliPayStrategy")
public class AliPayStrategyImpl implements PayStrategy{

    @Override
    public String pay(String type, String amount) {
        return String.format(MSG, PayEnum.ALI_PAY.getDescription(), amount);
    }
}


@Component("wechatPayStrategy")
public class WechatPayStrategyImpl implements PayStrategy{
    @Override
    public String pay(String type, String amount) {
        return String.format(MSG, PayEnum.WECHAT_PAY.getDescription(), amount);
    }
}


@Component("unionPayStrategy")
public class UnionPayStrategyImpl implements PayStrategy{
    @Override
    public String pay(String type, String amount) {
        return String.format(MSG, PayEnum.UNION_PAY.getDescription(), amount);
    }
}

  3、修改后的枚举类

public enum  PayEnum {

    ALI_PAY("ali", "支付宝支付", "aliPayStrategy"),
    WECHAT_PAY("wechat", "微信支付", "wechatPayStrategy"),
    UNION_PAY("union", "银联支付", "unionPayStrategy");

    private String type;

    private String description;

    private String beanName;

    PayEnum(String type, String description, String beanName) {
        this.type = type;
        this.description = description;
        this.beanName = beanName;
    }

    public String getType() {
        return type;
    }

    public String getDescription() {
        return description;
    }

    public String getBeanName() {
        return beanName;
    }

    public static PayEnum getByType(String type){
        if (type == null){
            return null;
        }
        for (PayEnum payEnum:values()
             ) {
            if (payEnum.getType().equals(type)){
                return payEnum;
            }
        }
        return null;
    }
}

  4、通过以下工具类,能够获取到PayStrategy实现类关联。

public class SpringContextUtil implements ApplicationContextAware {

    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;

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

    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }

    public static <T> T getBean(String name){
        return (T)getApplicationContext().getBean(name);
    }

    public static <T> T getBean(String name, Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }


}

  5、Service调用PayStrategy的工厂类,返回PayStrategy的实现类

public class PayStrategyFactory {

    /**
     * 根据type获取对应PayStrategy实现类
     * @param type
     * @return
     */
    public static PayStrategy getPayStrategy(String type){
        PayEnum payEnum = PayEnum.getByType(type);
        if (payEnum == null){
            return null;
        }
        return SpringContextUtil.getBean(payEnum.getBeanName(), PayStrategy.class);
    }
}

  通过这样的改造,当我们增加一个信用卡支付时,只需要添加一个PayStrategy的实现类,并在PayEnum枚举类添加一个信用卡支付的成员就可以了。

 

使用策略模式解决多重判断if-else问题

原文:https://www.cnblogs.com/chenrencun/p/13634268.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!