level_2
Github branch Level2 바로가기
기능
- 사용자로부터 사칙연산 또는 원의 넓이 선택 여부 입력
- 입력값에 결과는 이전 결과를 삭제하지 않고 저장
- 사용자로부터 "inquiry" 입력 시 저장 결과 전체 출력
- 사용자로부터 "remove" 입력 시 가장 먼저 입력한 값 삭제 ( 사칙 연산만 가능 )
- 사용자로부터 "exit" 입력 시 프로그램 종료
- 사용자의 잘못 된 입력에 대한 예외 처리
- 정수 입력이 아닌 경우
- 사칙연산 기호에 맞지 않는 입력인 경우
- 나누기의 경우 두 번째로 입력한 정수가 0인 경우
- 원의 넓이를 구하는 경우에서 입력 값 0이거나 0보다 작은 경우
App.java
public class App {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
ArithmeticCalculator<Double> arithmeticCalculator = new ArithmeticCalculator<>();
CircleCalculator circleCalculator = new CircleCalculator();
String flag = "";
while (!flag.equals("exit")) {
System.out.println("어떤 작업을 수행하시겠습니까? [사칙연산], [원의 넓이]");
boolean isValid = switch (sc.nextLine().trim()) {
case "사칙연산" -> toArithmetic(arithmeticCalculator);
case "원의 넓이" -> toCircle(circleCalculator);
default -> {
System.out.println("잘못된 입력입니다. \"사칙연산\" 또는 \"원의 넓이\" 를 입력해주세요\n");
yield false;
}
};
if (isValid) {
System.out.println("계산하시겠습니까? (exit 입력 시 종료)");
flag = sc.nextLine().trim();
}
}
}
private static boolean toArithmetic(ArithmeticCalculator arithmeticCalculator) {
System.out.println("사칙연산 계산기\n");
double firstNumberInput, secondNumberInput;
char operatorInput;
try {
System.out.print("첫 번째 숫자를 입력하세요: ");
firstNumberInput = Double.parseDouble(sc.nextLine().trim());
System.out.print("두 번째 숫자를 입력하세요: ");
secondNumberInput = Double.parseDouble(sc.nextLine().trim());
System.out.print("사칙연산 기호를 입력하세요: ");
operatorInput = sc.nextLine().trim().charAt(0);
} catch (NumberFormatException e) {
System.out.println("잘못된 입력입니다. 숫자를 입력하세요.");
return false;
} catch (InputMismatchException e) {
System.out.println(e.getMessage());
return false;
}
arithmeticCalculator.toArithmeticCalculator(firstNumberInput, secondNumberInput, operatorInput);
double calculate;
try {
calculate = arithmeticCalculator.calculate();
arithmeticCalculator.addCalculation(calculate);
System.out.println("[사칙연산] 결과 = " + calculate + "\n");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
return false;
}
System.out.println("[사칙연산]가장 먼저 저장된 연산 결과를 삭제하시겠습니까? (remove 입력 시 삭제)");
try {
String removeInput = sc.nextLine().trim();
if (removeInput.equals("remove")) {
arithmeticCalculator.opRemoveResult();
}
} catch (NoSuchElementException e) {
System.out.println(e.getMessage());
}
System.out.println("[사칙연산]저장된 연산결과를 조회하시겠습니까? (inquiry 입력 시 조회)");
try {
String removeInput = sc.nextLine().trim();
if (removeInput.equals("inquiry")) {
arithmeticCalculator.opInquiryResults(calculate);
}
} catch (NoSuchElementException e) {
System.out.println(e.getMessage());
}
return true;
}
private static boolean toCircle(CircleCalculator circleCalculator) {
System.out.println("원의 넓이 계산기\n");
double radius;
try {
System.out.print("반지름을 입력하세요: ");
radius = Double.parseDouble(sc.nextLine().trim());
} catch (NumberFormatException e) {
System.out.println("잘못된 입력입니다. 숫자를 입력하세요.");
return false;
}
circleCalculator.toCircleCalculator(radius);
try {
double area = circleCalculator.calculate();
circleCalculator.addCalculation(area);
System.out.println("[원의 넓이]결과 = " + area + "\n");
circleCalculator.opInquiryResults();
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
return false;
} catch (NoSuchElementException e) {
System.out.println(e.getMessage());
}
return true;
}
}
ArithmeticCalculator.java
@NoArgsConstructor
public class ArithmeticCalculator<T extends Number> extends Calculator {
private T firstNumber;
private T secondNumber;
private char operator;
@Override
double calculate() {
double result = 0;
if (Objects.equals(OperatorType.OPERATOR_ADD.getOperatorName(), operator)) {
result = new AddOperator().operate((double) firstNumber, (double) secondNumber);
} else if (Objects.equals(OperatorType.OPERATOR_SUBTRACT.getOperatorName(), operator)) {
result = new SubtractOperator().operate((double) firstNumber, (double) secondNumber);
} else if (Objects.equals(OperatorType.OPERATOR_MULTIPLY.getOperatorName(), operator)) {
result = new MultiplyOperator().operate((double) firstNumber, (double) secondNumber);
} else if (Objects.equals(OperatorType.OPERATOR_DIVIDE.getOperatorName(), operator)) {
result = new DivideOperator().operate((double) firstNumber, (double) secondNumber);
} else if (Objects.equals(OperatorType.OPERATOR_MOD.getOperatorName(), operator)) {
result = new ModOperator().operate((double) firstNumber, (double) secondNumber);
} else {
throw new IllegalArgumentException("[ +, -, /, *, % ] 이외에 입력되었습니다.");
}
return result;
}
public void toArithmeticCalculator(T firstNumberInput, T secondNumberInput, char operatorInput) {
this.firstNumber = firstNumberInput;
this.secondNumber = secondNumberInput;
this.operator = operatorInput;
}
public void opRemoveResult() {
if (getResults().isEmpty()) {
throw new NoSuchElementException("삭제할 연산 결과가 없습니다.");
}
System.out.println("remove = " + getResults().poll());
}
public void opInquiryResults(double num) {
if (getResults().isEmpty()) {
throw new NoSuchElementException("조회할 연산 결과가 없습니다.");
}
getResults().stream()
.filter(result -> result > num)
.forEach(System.out::println);
}
}
CircleCalculator.java
import java.util.NoSuchElementException;
public class CircleCalculator extends Calculator {
private final static double PI = 3.14159265358979323846;
private double radius;
public CircleCalculator() {
}
public void toCircleCalculator(double radius) {
this.radius = radius;
}
@Override
double calculate() {
if (radius <= 0) {
throw new IllegalArgumentException("반지름은 양수여야 합니다.");
}
return radius * radius * PI;
}
@Override
void opInquiryResults() {
if (getResults().isEmpty()) {
throw new NoSuchElementException("조회할 연산 결과가 없습니다.");
}
int index = 1;
for (Double result : getResults()) {
System.out.println(index + "번째 결과는 = " + result);
index++;
}
}
}
Operator.java
public interface Operator {
double operate(double firstNum, double secondNum);
}
AddOperator.java
public class AddOperator implements Operator{
@Override
public double operate(double firstNum, double secondNum) {
return firstNum + secondNum;
}
}
SubStractOperator.java
public class SubtractOperator implements Operator {
@Override
public double operate(double firstNumber, double secondNumber) {
return firstNumber - secondNumber;
}
}
MultiplyOperator.java
public class MultiplyOperator implements Operator {
@Override
public double operate(double firstNumber, double secondNumber) {
return firstNumber * secondNumber;
}
}
DivideOperator.java
public class DivideOperator implements Operator {
@Override
public double operate(double firstNumber, double secondNumber) {
if (secondNumber == 0) {
throw new IllegalArgumentException("나눗셈 연산에서 분모(두 번째 정수)에 0이 입력될 수 없습니다.");
}
return firstNumber / secondNumber;
}
}
ModOperator.java
public class ModOperator implements Operator {
@Override
public double operate(double firstNum, double secondNum) {
if (secondNum == 0) {
throw new IllegalArgumentException("나머지 연산에서 분모(두 번째 정수)에 0이 입력될 수 없습니다.");
}
return firstNum % secondNum;
}
}
문제점
ArithmeticCalculator에서 사칙연산 기호를 문자가 아닌 Enum 타입으로 변경할 수 있다.
App에 사칙연산과 원의 넓이를 구하는 구현 코드가 메서드로 분리되어 있지만
많은 코드들이 담겨 있다.