zoukankan      html  css  js  c++  java
  • 用工厂设计模式+策略什么模式,彻底干掉if else

    老哥哔哔叨

    无论是人生还是代码,都面临着很多的选择,代码里面充斥着无数的if / else,人生不也是一样吗?无数的分岔路口,我们无法避免这些选择,但是我们可以更优美的去做选择—设计模式

    谈恋爱的烦恼

    不巧,今天又到了发奖金的时间了,女朋友第一时间过来催债了。

    化悲伤为动力

    每次钱包空空如也,就更加刺激我努力写代码,我发现霸王龙这次居然一口气用了3个if,有进步啊。但是如果我发的奖金更多,岂不是要说出10几个if来。不行,我得给她讲讲设计模式教育教育她,告诉她如何干掉代码里的if / else

    if 伪代码

    public String getBonusPlan(Integer bonus) {
        if (bonus.equals(100)) {
            if (饿了) {
                return "吃呷哺火锅";
            }
            return "在考虑考虑";
        } else if (bonus.equals(300)) {
            if (饿了) {
                return "吃蜀大侠火锅";
            }
            return "在考虑考虑";
        } else if (bonus.equals(500)) {
            return "吃海底捞火锅";
        }
        // 一大波火锅来袭。。。。
    }
    复制代码

    工厂模式 + 策略模式

    这里不是标准的工厂模式,也不是标准的策略模式,是按照业务需要组合两者的使用。这个模式在工作中用到的情况会很多,如果大家有兴趣,我们可以单独写篇文章讲讲工厂和策略设计模式。

    策略模式登场

    • 首先定义一个总的接口类
    // 奖金接口
    public interface BonusService {
       // 奖金如何使用方法
       public String useBonusPlan (Integer bonus);
    }
    复制代码
    • 奖金使用方式一:去呷哺吃火锅
    public class XiabuBonusService implements BonusService {
        @Override
        public String useBonusPlan(Integer bonus) {
            if (饿了) {
                return "去呷哺吃" + bonus + "元的火锅";
            }
            return "在考虑考虑";
        }
    }
    复制代码
    • 奖金使用方式一:去蜀大侠吃火锅
    public class ShudaxiaBonusService implements BonusService {

        @Override
        public String useBonusPlan(Integer bonus) {
            if (饿了) {
                return "去蜀大侠吃" + bonus + "元的火锅";
            }
            return "在考虑考虑";
        }
    }
    复制代码
    • 奖金使用方式一:去海底捞吃火锅
    public class HaidilaoBonusService implements BonusService {

        @Override
        public String useBonusPlan(Integer bonus) {
            return "去海底捞吃" + bonus + "元的火锅";
        }
    }
    复制代码

    用上策略模式后的变化

    public String getBonusPlan(Integer bonus) {
        
        if (bonus.equals(100)) {
            XiabuBonusService xiabuBonusService = spring.getBean(XiabuBonusService.class);
            return xiabuBonusService.useBonusPlan(bonus);
        } else if (bonus.equals(300)) {
            ShudaxiaBonusService shudaxiaService = spring.getBean(ShudaxiaBonusService.class);
            return shudaxiaService.useBonusPlan(bonus);
        } else if (bonus.equals(500)) {
            HaidilaoBonusService haidilaoBonusService = spring.getBean(HaidilaoBonusService.class);
            return haidilaoBonusService.useBonusPlan(bonus);
        }
    }
    复制代码

    大家可以看到 getBonusPlan 这个方法可读性好了很多,我们将吃火锅算法封装到了一个一个的策略类里面,但是对于哪些情况下使用哪种算法的if判断,并没有减少呀。继续优化代码!

    简单工厂设计模式

    // 创建一个奖金工厂类
    public class BonusStrategyFactory {

        // 用map来保存如何使用奖金的策略类
        private static Map<Integer, BonusService> strategyMap
        = new ConcurrentHashMap<Integer, BonusService>();

        // 通过奖金多少查找对应的使用策略
        public  static BonusService getByBonus(Integer bonus){
            return strategyMap.get(bonus);
        }

        // 将奖金和对应的使用策略注册到map里
        public static void register(Integer bonus, BonusService bonusService){
            Assert.notNull(bonus,"bonus can't be null");
            strategyMap.put(bonus, bonusService);
        }
    }
    复制代码

    加上工厂设计模式后,代码的变化

    public String getBonusPlan(Integer bonus) {
        // 在工厂里通过奖金拿到对应的使用策略类
        BonusService strategyService = BonusStrategyFactory.getByBonus(bonus);
        // 调用策略类相应的方法
        return strategyService.getBonusPlan(bonus);
    }
    复制代码

    大家可以看到,策略设计模式 + 工厂设计模式,让我们的代码十分简洁,唯一的缺憾就是多了一些策略类,但是非常的解耦,以上代码只是演示伪代码。在真实复杂的业务场景中,设计模式能发挥非常重要的作用。

    将策略注册到 Map 中

    我们利用 spring 的 InitializingBean 这个接口来实现,拿蜀大侠那个类来举例。

    public class ShudaxiaBonusService implements BonusService, InitializingBean {

        @Override
        public String useBonusPlan(Integer bonus) {
            if (饿了) {
                return "去蜀大侠吃" + bonus + "元的火锅";
            }
            return "在考虑考虑";
        }

        @Override
        public void afterPropertiesSet() throws Exception {
            // 注册到Map中
            BonusStrategyFactory.register(300, this);
        }
    }
    复制代码

    老哥结语

    虽然私房钱咱藏不住,但是又通过这次惨痛的教训,学到一门新技术,挺好挺好,让暴风雨来的更猛烈些吧。

  • 相关阅读:
    JAVAOO 11 12 15 13 章
    JAVAOO 继承~接口 笔记
    JAVAOO 5~6章笔记
    JAVAOO 1—4章学习重点
    CSS超链接和导航
    XHTML基础
    ZooKeeper伪集群安装配置
    异常,常用类,集合
    继承,抽象,多态,接口
    java oo 第一周
  • 原文地址:https://www.cnblogs.com/itlaoge/p/14219658.html
Copyright © 2011-2022 走看看