1.提出问题:设计一个简单的计算器功能。
原始版本:
定义减法
private final static String ADD = "+";
public static void main(String[] args) {
System.out.println("请输入数字A");
Scanner scannerA = new Scanner(System.in);
double numberA = scannerA.nextDouble();
System.out.println("请输入数字B");
Scanner scannerB = new Scanner(System.in);
double numberB = scannerB.nextDouble();
System.out.println("请输入运算符C");
Scanner scannerC = new Scanner(System.in);
String operator = scannerC.next();
if (ADD.equalsIgnoreCase(operator)) {
System.out.println(numberA + numberB);
}
}
这样就实现了一个加法计算器,那么问题来了,如果我要为计算器新增减法功能呢?有些同学就说新增一个if判断不就好了?那么问题又来了,我有N个类都用了计算器我们是不是就要去N个地方去修改?是的,那么我们很容易就可以想到利用封装的思想将计算逻辑与控制台输入给分开,改造好的运算逻辑方法,如下:
/**
* 这里用到了封装思想,封装了运算方法,将输入和运算逻辑分开了
* @param numberA 输入的第一个值
* @param numberB 输入的第二个值
* @param operator 运算符
* @author WangHan
* @date 2019/1/21 16:15
*/
private static double operation(double numberA, double numberB, String operator) {
if (ADD.equalsIgnoreCase(operator)) {
return numberA + numberB;
} else if (SUBTRACT.equalsIgnoreCase(operator)) {
return numberA - numberB;
}else {
return 0;
}
}
这样尽管我有N多个地方输入计算值和计算符号,我也可以都调用这一个operation方法来计算结果!这就是封装的思想了。
继续:
如果此时要增加两个运算符*和/,需要修改operation方法让加减法也参与了重新编译,如果不小心将加减法改错那么就是坑爹!
增加需求,尽可能的扩展的来解决问题而不是去修改原来的代码
此时我们新增一个算法的父类Operation:
@Data
public class Operation {
public double numberA = 0;
public double numberB = 0;
public double getResult() {
return 0;
}
public static class OperationAdd extends Operation {
/**
* 重写getResult方法
*/
@Override
public double getResult() {
return numberA + numberB;
}
}
public static class OperationSub extends Operation {
/**
* 重写getResult方法
*/
@Override
public double getResult() {
return numberA - numberB;
}
}
}
并且新增两个子类OperationAdd 和OperationSub 去继承Operation分别实现加减算法。
新增一个工厂类OperationFactory:
class OperationFactory {
static Operation createOperation(double numberA, double numberB, String operator) {
Operation operation;
switch (operator) {
case "+":
operation = new Operation.OperationAdd();
operation.setNumberA(numberA);
operation.setNumberB(numberB);
return operation;
case "-":
operation = new Operation.OperationSub();
operation.setNumberA(numberA);
operation.setNumberB(numberB);
return operation;
default:
return null;
}
}
}
通过判断运算符去确定我要实例化那个算法的子类就可以了
这样在实现计算器功能的时候就用到了简单工厂模式,我们调用工厂类去实例化算法:
Optional<Operation> optional = Optional.ofNullable(OperationFactory.createOperation(numberA, numberB, operator));
optional.ifPresent(operation ->System.out.println("第三版计算结果:" + operation.getResult()));
学习到这里简答做个笔记!
网友评论