Skip to main content
Tweeted twitter.com/StackCodeReview/status/1422573024159617026
added 1607 characters in body
Source Link

Math Result

public class MathResult<T> {

    private final T t;

    public MathResult(T t) {
        this.t = t;
    }

    @Override
    public String toString() {
        String type = t == null ? "null" : t.getClass().getSimpleName();
        return "MathResult{" + type + ':' + t + '}';
    }
}

Operation

public class Operation<T> {

    public final Operands<T> operands;
    public final String operationSymbol;
    public final Function<Operands<T>, MathResult<T>> function;

    public Operation(Operands<T>  operands,String operationSymbol, Function<Operands<T>, MathResult<T>> function){
        this.operands = operands;
        this.operationSymbol = operationSymbol;
        this.function = function;
    }

    public MathResult<T> calculate() {
        return function.apply(operands);
    }

}

Operands

public class Operands<T> {

    private final T first;
    private final T second;

    public Operands(T single) {
        this(single, null);
    }

    public Operands(T first, T second) {
        if (first == null) {
            throw new IllegalArgumentException("first (single) operand must be set");
        }
        this.first = first;
        this.second = second;
    }

    public T get() {
        return getFirst();
    }

    public T getFirst() {
        return first;
    }

    public T getSecond() {
        if (second == null) {
            throw new IllegalArgumentException("second Operand does not exist");
        }
        return second;
    }
}

main Class

main Class

Math Result

public class MathResult<T> {

    private final T t;

    public MathResult(T t) {
        this.t = t;
    }

    @Override
    public String toString() {
        String type = t == null ? "null" : t.getClass().getSimpleName();
        return "MathResult{" + type + ':' + t + '}';
    }
}

Operation

public class Operation<T> {

    public final Operands<T> operands;
    public final String operationSymbol;
    public final Function<Operands<T>, MathResult<T>> function;

    public Operation(Operands<T>  operands,String operationSymbol, Function<Operands<T>, MathResult<T>> function){
        this.operands = operands;
        this.operationSymbol = operationSymbol;
        this.function = function;
    }

    public MathResult<T> calculate() {
        return function.apply(operands);
    }

}

Operands

public class Operands<T> {

    private final T first;
    private final T second;

    public Operands(T single) {
        this(single, null);
    }

    public Operands(T first, T second) {
        if (first == null) {
            throw new IllegalArgumentException("first (single) operand must be set");
        }
        this.first = first;
        this.second = second;
    }

    public T get() {
        return getFirst();
    }

    public T getFirst() {
        return first;
    }

    public T getSecond() {
        if (second == null) {
            throw new IllegalArgumentException("second Operand does not exist");
        }
        return second;
    }
}

main Class

Source Link

Java OOP Calculator (no GUI)

i have created an object orientated Calculator without GUI.

i have provided only the most important parts of the code. I want to add another review question for those parts (especially: MathResult and Operands)

Interface Calculator

public interface Calculator {
    MathResult<?> calculate(String operation);
}

Interface OperationParser

public interface OperationParser<T> {
    boolean matches(String operation);
    Operation<T> getOperation();
}

example-implementation: SimpleCalculator

public class SimpleCalculator implements Calculator {

    private final List<OperationParser<?>> operationParsers = new ArrayList<>();

    public SimpleCalculator(){
        operationParsers.add(new SimpleInfixArithmeticOperationParser(MathContext.DECIMAL64));
        operationParsers.add(new SimpleTrigonometricOperationParser());
    }

    @Override
    public MathResult<?> calculate(String input) {
        Optional<OperationParser<?>> parser = operationParsers.stream().filter(ip -> ip.matches(input)).findAny();
        if(parser.isPresent()){
            System.out.println("calculating "+parser.get().getOperation());
            return parser.get().getOperation().calculate();
        }else {
            throw new IllegalArgumentException("no valid parser for input '"+input+"' found");
        }
    }

}

main Class

public class CalculatorApp {

    public static void main(String[] args){
        final Calculator calculator = new SimpleCalculator();
        final Scanner scanner = new Scanner(System.in);
        final Pattern exitPattern = Pattern.compile("[eE][xX][iI][tT]");
        while (true) {
            String line = scanner.nextLine();
            if(exitPattern.matcher(line).matches()){
                break;
            }
            try {
                MathResult<?> result = calculator.calculate(line);
                System.out.println("result: " + result);
            }catch (Exception e){
                System.out.println("error: " + e);
            }
        }

    }
}