这个java计算器程序能更简化吗?

这个java计算器程序能更简化吗?,java,code-cleanup,Java,Code Cleanup,我是java的初学者,这是一个简单的计算器代码,我在教程的帮助下编写的。这工作得很好,但正如你所看到的,他们在这个程序中没有“构造函数”!而它们只是一个扫描对象! 这个程序是否可以更简化一些,以它的结构和方法,作为我学习的一个例子 import java.util.Scanner; public class apples { public static void main(String args[]){ Scanner calculator = new Scanner(System.i

我是java的初学者,这是一个简单的计算器代码,我在教程的帮助下编写的。这工作得很好,但正如你所看到的,他们在这个程序中没有“构造函数”!而它们只是一个扫描对象! 这个程序是否可以更简化一些,以它的结构和方法,作为我学习的一个例子

import java.util.Scanner; 
public class apples {
public static void main(String args[]){
    Scanner calculator = new Scanner(System.in);
    double fnum, snum, answer;

    System.out.println("Enter first number: ");
    fnum = calculator.nextDouble();
    System.out.println("Enter second number: ");
    snum = calculator.nextDouble();
    System.out.println("enter any operator: ");
    String op = calculator.next();
    switch (op){
    case ("x") :
        answer = fnum * snum;
        System.out.println(answer);
        break;

    case ("/") :
        answer = fnum / snum;
    System.out.println(answer);
    break;

    case ("+") :
        answer = fnum + snum;
    System.out.println(answer);
    break;

    case ("-") :
        answer = fnum - snum;
    System.out.println(answer);
    break;


    }

    }





}

一个想法是使用更多的功能样式来减少冗余的操作员和丑陋的外壳开关,并使代码更易于维护:

import java.util.*;
public class apples {
    protected static final Map<String, BinOp> operators = new HashMap<String, BinOp>() {{
        put("+", new BinOp() { public double calc(double op1, double op2) { return op1 + op2; }; });
        put("-", new BinOp() { public double calc(double op1, double op2) { return op1 - op2; }; });
        put("x", new BinOp() { public double calc(double op1, double op2) { return op1 * op2; }; });
        put("/", new BinOp() { public double calc(double op1, double op2) { return op1 / op2; }; });
    }};
    public static void main(String args[]){
        Scanner calculator = new Scanner(System.in);
        double fnum, snum, answer;

        System.out.println("Enter first number: ");
        fnum = calculator.nextDouble();
        System.out.println("Enter second number: ");
        snum = calculator.nextDouble();
        System.out.println("enter any operator: ");
        String op = calculator.next();
        BinOp opFunction = operators.get(op);
        answer = opFunction.calc(fnum, snum);
        System.out.println(answer);
    }
}

interface BinOp {
    double calc(double op1, double op2);
}
它使您的代码更具可读性和可维护性

因为我非常喜欢枚举:

import java.util.*;
public class apples {
    public static void main(String args[]){
        Scanner calculator = new Scanner(System.in);
        double fnum, snum, answer;

        System.out.println("Enter first number: ");
        fnum = calculator.nextDouble();
        System.out.println("Enter second number: ");
        snum = calculator.nextDouble();
        System.out.println("enter any operator: ");
        String op = calculator.next();
        Operation operator = Operation.get(op);
        answer = operator.calc(fnum, snum);
        System.out.println(answer);
    }
}

enum Operation {
    ADD("+") {
        public double calc(double op1, double op2) {
            return op1 + op2;
        }
    },
    SUB("-") {
        public double calc(double op1, double op2) {
            return op1 - op2;
        }
    },
    MUL("x") {
        public double calc(double op1, double op2) {
            return op1 * op2;
        }
    },
    DIV("/") {
        public double calc(double op1, double op2) {
            return op1 / op2;
        }   
    },
    ;

    Operation(String op) {
        this.op = op;
    }
    protected String op;
    public abstract double calc(double op1, double op2);
    public static Operation get(String op) {
        for (Operation operation : values()) {
            if (operation.op.equals(op)) {
                return operation;
            }
        }
        throw new RuntimeException("Not implemented!");
    }
}
您也可以在其他地方使用,如:

answer = Operation.MUL(2, 3);

并且可以轻松地迭代所有操作,获取名称等。

更新----------------------

这是我的解决方案;):

启动器(也可以来自servlet,例如,任何您想要的):

这里是
计算器
类:

public class Calculator {

    private final Operands operands;

    private final OperationType operationType;

    public Calculator(String leftOperand, String rightOperand, String operationType) {
        this.operands = new Operands(leftOperand,  rightOperand);
        this.operationType = OperationType.transform(operationType);;
    }

    public double calculate() {
        return operationType.calculate(operands);
    }
}
final class Operands {

    private final double leftOperand;

    private final double rightOperand;

    public Operands(String leftOperand, String rightOperand) {
        this.leftOperand = Double.parseDouble(leftOperand);
        this.rightOperand = Double.parseDouble(rightOperand);
    }

    public final double getLeftOperand() {
        return leftOperand;
    }

    public final double getRightOperand() {
        return rightOperand;
    }
}
这里是不可变的
操作数
类:

public class Calculator {

    private final Operands operands;

    private final OperationType operationType;

    public Calculator(String leftOperand, String rightOperand, String operationType) {
        this.operands = new Operands(leftOperand,  rightOperand);
        this.operationType = OperationType.transform(operationType);;
    }

    public double calculate() {
        return operationType.calculate(operands);
    }
}
final class Operands {

    private final double leftOperand;

    private final double rightOperand;

    public Operands(String leftOperand, String rightOperand) {
        this.leftOperand = Double.parseDouble(leftOperand);
        this.rightOperand = Double.parseDouble(rightOperand);
    }

    public final double getLeftOperand() {
        return leftOperand;
    }

    public final double getRightOperand() {
        return rightOperand;
    }
}
此处是包含逻辑的
OperationType
enum:

enum OperationType {

    ADDITION("+") {
        public double calculate(Operands operands) {
            return operands.getLeftOperand() + operands.getRightOperand();
        }
    },
    SUBTRACTION("-") {
        public double calculate(Operands operands) {
            return operands.getLeftOperand() - operands.getRightOperand();
        }
    },
    MULTIPLICATION("*") {
        public double calculate(Operands operands) {
            return operands.getLeftOperand() * operands.getRightOperand();
        }
    },
    DIVISION("/") {
        public double calculate(Operands operands) {
            return operands.getLeftOperand() / operands.getRightOperand();
        }
    };

    private String operationType;

    private OperationType(String operationType) {
        this.operationType = operationType;
    }

    abstract double calculate(Operands operands);

    static OperationType transform(String operationType) {
        for (OperationType ot : values()) {
            if (ot.operationType.equals(operationType)) {
                return ot;
            }
        }
        throw new IllegalArgumentException("Unknown operator, please redo your operation.");
    }
}

请把它移到请处。为什么类名是apples?你在做计算器,对吗?养成使用有意义名称的习惯这段代码已经过于简单了。因此,没有必要进一步简化它。您可以将
系统.out.println
移动到
开关的下方,这样可以节省三行重复代码。@codesparkle如果对程序没有更多要求,OOP化的解决方案只会获得毫无意义的复杂性。很多时候,我发现自己盯着一本书中一段完全没有动机的代码,想知道为什么一个人会编写这样一个怪物,而显然更简单的解决方案是可行的。紧张感和放松感是良好教育的关键,但实现这一点并非易事。在您的示例中,如果添加新操作,您将触及两个位置:变换和计算。枚举更像是简单的值持有者,请参见我的示例:)。另一件事是将getElement、askForOperand和askForOperator组合成一个函数,例如getElement(scanner:scanner,askuser:String):String,因为您的计算器构造函数得到3个字符串。@Anton Bessonov是的,您是对的:)在这个小例子中,我没有遵循打开/关闭原则:(Enum很可能看起来像接口一样是一个抽象。在这种情况下,OperationType将(或者更确切地说应该)引发一个良好实现的策略模式。因此,当必须有新的运算符出现时,无需接触计算器类,只需接触OperationType Enum。@Anton Bessonov我刚刚更新了代码;)我喜欢逻辑,可维护的代码:)谢谢。。。但我还没有学会“枚举”。:(