前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何去除代码中的多次if而引发的一连串面试问题

如何去除代码中的多次if而引发的一连串面试问题

作者头像
JavaQ
发布2020-03-26 11:01:45
4450
发布2020-03-26 11:01:45
举报
文章被收录于专栏:JavaQJavaQ

面试官:有如下的代码,如何去除代码中的if?

代码语言:javascript
复制
    public int calculate(int a, int b, String action) {
        if ("ADD".equals(action)) {
            return a + b;
        }

        if ("MUL".equals(action)) {
            return a * b;
        }

        if ("DIV".equals(action)) {
            return a / b;
        }

        if ("SUB".equals(action)) {
            return a - b;
        }

        throw new RuntimeException("action unknown");
    }

小白:巴拉巴拉写了一堆代码,代码如下:

代码语言:javascript
复制
public interface Calculator {
    int execute(int a, int b);
}

public class Addition implements Calculator {
    @Override
    public int execute(int a, int b) {
        return a + b;
    }
}

public class Subtraction implements Calculator {
    @Override
    public int execute(int a, int b) {
        return a - b;
    }
}

public class Multiplication implements Calculator {
    @Override
    public int execute(int a, int b) {
        return a * b;
    }
}

public class Division implements Calculator {
    @Override
    public int execute(int a, int b) {
        return a / b;
    }
}

public class CalculatorHolder {
    private static Map<String, Calculator> calculatorMap = new HashMap<>();

    static {
        calculatorMap.put("ADD", new Addition());
        calculatorMap.put("SUB", new Subtraction());
        calculatorMap.put("MUL", new Multiplication());
        calculatorMap.put("DIV", new Division());
    }

    publicstatic Calculator getCalculator(String action) {
        return calculatorMap.get(action);
    }
}

# 使用
CalculatorHolder.getCalculator( "ADD").execute(1,2);
CalculatorHolder.getCalculator( "MUL").execute(1,2);

面试官:你的这种解决方案,有人说使用了工厂模式,你觉得是吗?

小白:不是,真正的工厂模式有两种:工厂方法和抽象工厂。工厂方法使用继承,首先定义一个抽象父类工厂,然后定义子类工厂,把工厂要创建的对象委托给子工厂类,子工厂类实现父工厂类中要创建对象的方法。抽象工厂使用对象组合,首先定义一个工厂接口,然后定义工厂接口实现类,在实现类中实现接口的方法来创建对象,最后使用组合将接口实现类注入到要创建对象的地方。还有一种是简单工厂,但它不能算是真正意义上的设计模式,就是通过ifelse方式实现的。

面试官:你觉得工厂模式有什么优缺点?

小白:优点就是扩展容易,也不用再修改以前的代码,新增对象创建工厂即可,减少对象创建的依赖和强耦合。缺点就是会产生很多的工厂类或对象类,管理上会麻烦些,代码变的更多了。

面试官:你刚刚的这种解决方案,如果对象的生命周期是由Spring容器来管理的,也就是bean的实例化是在Spring容器启动时发生的,如何将Addition这种对象实例注入到calculatorMap中?

小白:有两种方式,一种是将calculatorMap中的key和value(bean的id)配置到Spring的xml声明文件中,另一种是通过编码的方式,自定义一个类实现Spring的ApplicationContextAware接口和InitializingBean接口,在类中声明属性一个ApplicationContext,通过setApplicationContext将这个属性指向Spring容器中的应用上下文ApplicationContext对象,然后实现afterPropertiesSet方法,通过applicationContext.getBeansOfType(Calculator.class)获取Calculator接口的所有实现类,结果是一个Map,key是bean的name,value是bean的实例对象,然后遍历这个Map,将元素注入到calculatorMap中。

面试官:你还能用其它设计模式去除if吗?

小白:策略模式。

面试官:说一下你理解的策略模式?

小白:在运行时,通过不同的策略(创建或引用不同的对象)改变类的行为,其实就是根据实现类的不同,动态的调用不同类的相同方法。

面试官:能不能写一下具体代码?

小白:一顿操作,霹雳吧啦,代码如下:

代码语言:javascript
复制
public class CalculatorHolder {

    private Calculator calculator;

    public CalculatorHolder(Calculator calculator) {
        this.calculator = calculator;
    }

    public int execute(int a, int b){
        return calculator.execute(a, b);
    }
}

CalculatorHolder ch = new CalculatorHolder(new Addition());
ch.execute(1, 2);

ch = new CalculatorHolder(new Subtraction());
ch.execute(1, 2);

面试官:策略模式有什么优缺点?

小白:优点就是可以解决像ifelse这样的不好维护的代码,做到对扩展开放、对修改关闭。缺点就是也会产生很多像Addition等这样的代码,导致类膨胀。

面试官:你刚刚说到开闭原则,设计模式还有其它什么原则?

小白:里氏替换原则,任何基类可以出现的地方,子类一定可以出现;依赖倒置原则,面向接口编程,依赖于抽象而不依赖于具体实现;单一职责原则,一个类应该只负责一项职责,做到职责单一;迪米特法则,一个对象应该对其它对象保持最少的了解;接口隔离原则,类和类之间应该建立在最小接口上。

面试官:解释一下接口隔离原则的内容?

小白:......巴拉巴拉......


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JavaQ 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档