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");
}
}
}
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
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);
}
}
}
}
Operation
. \$\endgroup\$