面试之设计模式(简单工厂模式)

案例

在面试时,面试官让你通过面对对象语言,用Java实现计算器控制台程序,要求输入两个数和运算符号,得出结果。大家可能想到是如下:

public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入任意数1");
        double numberA = scanner.nextDouble();
        System.out.println("请输入任意数2");
        double numberB = scanner.nextDouble();
        System.out.println("请选择运算符(+、-、*、/)");
        String operation = scanner.next();
        double result = 0L;
        switch (operation) {
    
    
            case "+" :
                result = numberA + numberB;
                break;
            case "-" :
                result = numberA - numberB;
                break;
            case "*" :
                result = numberA * numberB;
                break;
            case "/" :
                result = numberA / numberB;
                break;
            default:

                break;
        }
        System.out.println("结果:" + result);
        scanner.close();
    }

上面的代码确实能够满足面试所需求的,但是你觉得就真的这么简单吗。
写出上列代码只能说明你有一定的代码基础能力,如果是刚毕业能写出来还算OK,但是如果你已经工作一年以上还写出这种代码,只能说平常确实没有进行过学习。

通过这道题目可以考验你对Java的封装、继承、多态、设计模式的理解。

封装

分离业务逻辑和界面逻辑,降低耦合度,实现易维护、易扩展
Operation运算类

public class Operation {
    
    

    public static double GetResult(double numberA, double numberB, String operation) {
    
    
        double result = 0L;
        switch (operation) {
    
    
            case "+" :
                result = numberA + numberB;
                break;
            case "-" :
                result = numberA - numberB;
                break;
            case "*" :
                result = numberA * numberB;
                break;
            case "/" :
                result = numberA / numberB;
                break;
            default:

                break;
        }
        return result;
    }

}

客户端代码

@SpringBootTest
class ProgramTest {
    
    

    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入任意数1");
        double numberA = scanner.nextDouble();
        System.out.println("请输入任意数2");
        double numberB = scanner.nextDouble();
        System.out.println("请选择运算符(+、-、*、/)");
        String operation = scanner.next();

        double result = Operation.GetResult(numberA, numberB, operation);
        System.out.println("结果:" + result);
        scanner.close();
    }
}

这样就将业务与页面分离开,后面其他程序需要用到计算业务,直接复用Operation就可。
但是依旧达不到灵活的可修改和可扩展,比如现在需要增加一个开根运算,那只能改Operation,在switch中增加一个分支,在复杂业务中,改动原有逻辑有可能会出现问题。
要想实现灵活的可修改和可扩展,就需要使用到继承和多态

继承、多态

Operation 计算器的父类

public abstract class Operation {
    
    
    private double numberA;

    private double numberB;

    public abstract double getResult();

    public double getNumberA() {
    
    
        return numberA;
    }

    public void setNumberA(double numberA) {
    
    
        this.numberA = numberA;
    }

    public double getNumberB() {
    
    
        return numberB;
    }

    public void setNumberB(double numberB) {
    
    
        this.numberB = numberB;
    }
}

加法

public class Add extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        return getNumberA() + getNumberB();
    }
}

减法

public class Sub extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        return getNumberA() - getNumberB();
    }
}

加减乘除写成运算类的子类,继承运算类后,重写GetResult()方法,这样修改任何一个算法,都不需要提供其他算法的代码了,但问题来了,如何让计算器知道我是希望使用哪一种算法呢?

简单工厂模式

简单运算工厂类

public class OptionerFactory {
    
    
    public static Operation createOperation(String operation) {
    
    
        Operation oper = null;
        switch (operation) {
    
    
            case "+":
                oper = new Add();
                break;
            case "-":
                oper = new Sub();
                break;
        }
        return oper;
    }
}

只需要输入运算符号,工厂就实例化出合适的对象,通过多态,返回父类的方式实现了计算器的结果

客户端代码

public static void main(String[] args) {

    Scanner scanner = new Scanner(System.in);
    System.out.println("请输入任意数1");
    double numberA = scanner.nextDouble();
    System.out.println("请输入任意数2");
    double numberB = scanner.nextDouble();
    System.out.println("请选择运算符(+、-、*、/)");
    String oper = scanner.next();
    Operation operation = OptionerFactory.createOperation(oper);
    operation.setNumberA(numberA);
    operation.setNumberB(numberB);
    double result = operation.getResult();
    System.out.println("结果:"+result);
}

测试结果
在这里插入图片描述

总结

题目很简单,就像在学校解数学题一样,解法有很多种,但是大部分人只会最简单的一种,你能写出多种解法,说明你对这方面有深入学习过。而面试官要考验的就是这个。

猜你喜欢

转载自blog.csdn.net/RoyRaoHR/article/details/129157560
今日推荐