利用设计模式消灭掉代码中的if-else

12 篇文章 0 订阅
2 篇文章 0 订阅
本文介绍了如何通过工厂模式和策略模式来改进含有大量if-else的代码,提高代码的可读性和可扩展性。首先定义水果策略接口,然后创建工厂来管理各种水果的实现类,每个实现类在初始化后自动注册到工厂。通过这种方式,当需要添加新的水果类型如西瓜时,只需新增一个实现类并注册,无需修改原有代码。这种优化符合OCP原则,使得代码更加整洁和易于维护。
摘要由CSDN通过智能技术生成

1 问题描述

我们先来看下述代码

/**
 * @Author ChenJiahao(程序员五条)
 * @Date 2021/8/23 20:22
 */
public class Main {
    public static void main(String[] args) {
        // String fruit = "apple";
        // String fruit = "orange";
        String fruit = "banana";
        if ("apple".equals(fruit)){
            System.out.println("吃到了  Apple ~~~~~~~");
        }else if ("banana".equals(fruit)){
            System.out.println("吃到了  Banana ~~~~~~");
        }else {
            System.out.println("吃到了  Orange ~~~~~~");
        }
    }
}

看似么得问题,if一判断,然后做出对应的输出。

缺点:如果还想吃西瓜的话,还得继续加if判断,同时也不方便水果的统一管理,并且这样做不符合OCP原则(对扩展开放,对修改关闭)。

2 利用工厂模式+策略模式消灭掉代码中的if-else

核心思想:通过工厂获取对应的策略(具体的水果),通过策略接口去执行具体的方法

优点:代码简洁,方便管理,扩展性较好

步骤

2.1 创建水果策略接口(由具体的水果抽象出来的),继承InitializingBean接口。

/**
 * @Author ChenJiahao(程序员五条)
 * @Date 2021/8/23 20:42
 */
public interface FruitHandler extends InitializingBean {
    void eatFruit();
}

说明

继承InitializingBean的原因是它包含一个方法afterPropertiesSet,这个方法将在所有的属性被初始化后调用。在这里的作用是让实现类在初始化后就将自身自动注册到工厂中(工厂的Map中)。

2.2 创建工厂

/**
 * @Author ChenJiahao(程序员五条)
 * @Date 2021/8/23 20:44
 */
public class FruitStrategyFactory {
    private static Map<String, FruitHandler> fruitStrategyMap = new HashMap<>();

    public static FruitHandler getStrategyMap(String fruitName){
        return fruitStrategyMap.get(fruitName);
    }

    public static void registerHandler(String handlerName, FruitHandler handler){
        fruitStrategyMap.put(handlerName,handler);
    }
}

说明

transferStrategyMap:用来存储具体的水果策略,key为上述if中的判断条件,value为FruitHandler类型的实现类(相当于把原先的if判断交给了map)

getTransferStrategyMap():获取对应的FruitHandler(key通常为原先if中的判断条件,需要自己去规定)

registerHandler():在策略接口的实现类在afterPropertiesSet()方法中利用registerHandler()方法将当前实现类注册到fruitStrategyMap中

2.3 创建水果策略接口的实现类

注意:需要加@Component(SpringBoot项目)

2.3.1 Apple

/**
 * @Author ChenJiahao(程序员五条)
 * @Date 2021/8/23 20:48
 */
@Component
public class AppleHandler implements FruitHandler {
    @Override
    public void eatFruit() {
        System.out.println("吃到了  Apple ~~~~~~");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        FruitStrategyFactory.registerHandler("apple",this);
    }
}

2.3.2 Banana

/**
 * @Author ChenJiahao(程序员五条)
 * @Date 2021/8/23 20:49
 */
@Component
public class BananaHandler implements FruitHandler {
    @Override
    public void eatFruit() {
        System.out.println("吃到了  Banana ~~~~~~");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        FruitStrategyFactory.registerHandler("banana",this);
    }
}

2.3.3 Orange

/**
 * @Author ChenJiahao(程序员五条)
 * @Date 2021/8/23 20:51
 */
@Component
public class OrangeHandler implements FruitHandler {
    @Override
    public void eatFruit() {
        System.out.println("吃到了  Orange ~~~~~~");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        FruitStrategyFactory.registerHandler("orange",this);
    }
}

说明

1.在eatFruit()方法中进行原先的if中要执行的方法

2.在afterPropertiesSet()方法中将自身注册到工厂的Map中

3 改造后的调用方式

FruitStrategyFactory.getStrategyMap(fruit).eatFruit();

4 扩展西瓜

步骤

1.编写WatermelonHandler类,实现FruitHandler接口

2.在eatFruit()方法中编写:System.out.println(“吃到了 Watermelon ~~~~~~”);

3.在afterPropertiesSet()中将WatermelonHandler注册到工厂的Map中

以上三步即可,原先调用的代码不需要任何改变

5 比较

// 使用设计模式之前
if ("apple".equals(fruit)){
    System.out.println("吃到了  Apple ~~~~~~~");
}else if ("banana".equals(fruit)){
    System.out.println("吃到了  Banana ~~~~~~");
}else {
    System.out.println("吃到了  Orange ~~~~~~");
}

// 使用设计模式之后
FruitStrategyFactory.getStrategyMap(fruit).eatFruit();

6 总结

1.工厂

2.策略接口

3.策略实现类

4.面向工厂Map中的策略去调用

注意:工厂Map中的key,需要自己根据实际情况去制定(这个key通常为原先if中的判断条件)

7 注意事项

如果是普通的Java项目,策略接口就不用继承InitializingBean了(没意义了),也不需要@Component

在调用FruitStrategyFactory的getStrategyMap()方法之前手动将具体的实现类注册到工厂的Map中。

示例如下

// 将各个实现类手动注册到工厂的Map中
FruitStrategyFactory.registerHandler("apple",new AppleHandler());
FruitStrategyFactory.registerHandler("banana",new BananaHandler());
FruitStrategyFactory.registerHandler("orange",new OrangeHandler());
// 调用
FruitStrategyFactory.getStrategyMap(fruit).eatFruit();

最后

想阅读更多设计模式相关文章,欢迎到我的专栏【学习笔记】、【设计模式】中去查看

感谢大家看到这里,文章如有不足,欢迎大家指出;如果你觉得写的还不错,那就给我一个赞吧,欢迎大家关注和转发文章!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五条Programmer

比心~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值