美文网首页
策略模式和简单工厂模式替代IF ELSE 和Switch

策略模式和简单工厂模式替代IF ELSE 和Switch

作者: 久伴我还是酒伴我 | 来源:发表于2020-05-21 11:04 被阅读0次

    简介

    这两天在搞一个调度任务,通过XXL-JOB定期执行未执行的数据,数据类型大概有八九种,不同的类型不同的业务逻辑处理,需要调用不同的方法进行处理,可能类型少点可以通过IF ELSE 或者Switch 去实现,但是多了,代码看着很不优雅,实在看不下去了,就通过策略模式和简单工厂模式简单改造了下。

    改造前

    代码中method是实际执行方法,这里咱们用method代替,这么多case 感觉很low

     if (CollectionUtils.isNotEmpty(invoiceWbAsynList)) {
                invoiceWbAsynList.stream().forEach(v -> {
                    switch (v.getType()) {
                        case 0:
                        case 1:
                            method1(v);
                            break;
                        case 2:
                            method2(v);
                            break;
                        case 3:
                            method3(v);
                            break;
                        case 4:
                           method4(v);
                            break;
                        case 5:
                            method5(v);
                            break;
                        case 6:
                            method6(v);
                            break;
                        case 7:
                            method7(v);
                            break;
                        case 8:
                            method8(v);
                        default:
                            method9(v);
                    }
                });
            }
    

    改造后

    咱们改造后的再看下,就这么几行代码,瞬间高大上了。

     if (CollectionUtils.isNotEmpty(invoiceWbAsynList)) {
                invoiceWbAsynList.stream().forEach(v -> {
                    factoryForStrategy.getStrategy(WbAsynTypeEnum.getVal(v.getType()).getMethod()).execute(v);
                });
     }
    

    举例

    上述代码是实际业务中产生的,为了更直观的了解,咱们举个简单的例子。
    当前社会,手机是必不可少的,有很多人都是两三个手机(ps:我只有一个手机),咱们使用不同的手机(苹果、华为、小米、)打电话来模仿再实际业务中要调用不同的方法。

    创建 PhoneStrategy

    package com.glj.webservice.demo.strategy;
    
    public interface PhoneStrategy {
        // 打电话
        String call(String phoneName);
    }
    

    创建 AppleStrategy

    package com.glj.webservice.demo.strategy.impl;
    
    import com.glj.webservice.demo.strategy.PhoneStrategy;
    import org.springframework.stereotype.Component;
    
    /**
     * 苹果手机打电话
     */
    @Component("apple")
    public class AppleStrategy implements PhoneStrategy {
        @Override
        public String call(String phoneName) {
            System.out.println("使用"+phoneName+"手机打电话");
            return "使用"+phoneName+"手机打电话";
        }
    }
    

    创建 HuaWeiStrategy

    package com.glj.webservice.demo.strategy.impl;
    
    import com.glj.webservice.demo.strategy.PhoneStrategy;
    import org.springframework.stereotype.Component;
    
    /**
     * 华为手机打电话
     */
    @Component("huawei")
    public class HuaWeiStrategy implements PhoneStrategy {
        @Override
        public String call(String phoneName) {
            System.out.println("使用"+phoneName+"手机打电话");
            return "使用"+phoneName+"手机打电话";
        }
    }
    
    

    创建 XiaoMiStrategy

    package com.glj.webservice.demo.strategy.impl;
    
    import com.glj.webservice.demo.strategy.PhoneStrategy;
    import org.springframework.stereotype.Component;
    
    /**
     * 小米手机打电话
     */
    @Component("xiaomi")
    public class XiaoMiStrategy implements PhoneStrategy {
        @Override
        public String call(String phoneName) {
            System.out.println("使用"+phoneName+"手机打电话");
            return "使用"+phoneName+"手机打电话";
        }
    }
    
    

    创建简单工厂PhoneStrategyFactory

    package com.glj.webservice.demo.strategy.factory;
    
    import com.glj.webservice.demo.strategy.PhoneStrategy;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.Map;
    import java.util.Optional;
    import java.util.concurrent.ConcurrentHashMap;
    
    @Service
    public class PhoneStrategyFactory {
        @Autowired
        Map<String, PhoneStrategy> strategys = new ConcurrentHashMap<>();
    
        public PhoneStrategy getStrategy(String component){
            PhoneStrategy strategy = strategys.get(component);
            Optional.ofNullable(strategy).orElseThrow(RuntimeException::new);
            return strategy;
        }
    }
    

    关键点: AutoWired一个Map<String, PhoneStrategyFactory > 这个会在初始化的时候将所有的PhoneStrategyFactory 实现类自动加载到Map中。使用concurrentHashMap是防止多线程操作的时候出现问题。同时还要注意@Service注解。

    Swagger测试

    请求参数和结果

    image.png
    image.png

    结束语:
    其实策略模式在我们日常开发中,不管是算法还是业务逻辑处理,主要是针对相同请求参数和相同的返回参数,不同的业务处理,用到的概率会很多,如果请求参数不一致,或者返回参数不一致,策略模式还是不建议使用的(除非通过泛型或者特殊手段处理)。

    相关文章

      网友评论

          本文标题:策略模式和简单工厂模式替代IF ELSE 和Switch

          本文链接:https://www.haomeiwen.com/subject/vqdoohtx.html