기술 과제입니다.
public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("첫 번째 숫자를 입력하세요: ");
// Scanner를 사용하여 양의 정수를 입력받고 적합한 타입의 변수에 저장합니다.
System.out.print("두 번째 숫자를 입력하세요: ");
// Scanner를 사용하여 양의 정수를 입력받고 적합한 타입의 변수에 저장합니다.
}
}
charAt(0)
)public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
...
System.out.print("사칙연산 기호를 입력하세요: ");
// 사칙연산 기호를 적합한 타입으로 선언한 변수에 저장합니다.
}
}
if
switch
public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
...
int result = 0;
/* 제어문을 활용하여 위 요구사항을 만족할 수 있게 구현합니다.*/
System.out.println("결과: " + result);
}
}
public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
/* 반복문 사용 해서 연산을 반복 */
...
System.out.println("결과: " + result);
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
/* exit을 입력 받으면 반복 종료 */
}
}
public class Calculator {
/* 연산 결과를 저장하는 컬렉션 타입 필드 선언 및 생성 */
public 반환타입 calculate(...매개변수) {
/* 위 요구사항에 맞게 구현 */
/* return 연산 결과 */
}
}
public class App {
public static void main(String[] args) {
/* Calculator 인스턴스 생성 */
Scanner sc = new Scanner(System.in);
/* 반복문 시작 */
System.out.print("첫 번째 숫자를 입력하세요:");
int num1 = sc.nextInt();
System.out.print("두 번째 숫자를 입력하세요:");
int num2 = sc.nextInt();
System.out.print("사칙연산 기호를 입력하세요: ");
char operator = sc.next().charAt(0);
/* 위 요구사항에 맞게 소스 코드 수정 */
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
...
/* 반복문 종료 */
}
}
public class Calculator {
/* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/
public 반환타입 calculate(...매개변수) {
...
}
/* Getter 메서드 구현 */
/* Setter 메서드 구현 */
}
public class App {
public static void main(String[] args) {
/* Calculator 인스턴스 생성 */
Scanner sc = new Scanner(System.in);
/* 반복문 시작 */
System.out.print("첫 번째 숫자를 입력하세요:");
int num1 = sc.nextInt();
System.out.print("두 번째 숫자를 입력하세요:");
int num2 = sc.nextInt();
System.out.print("사칙연산 기호를 입력하세요: ");
char operator = sc.next().charAt(0);
/* 위 요구사항에 맞게 소스 코드 수정 */
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
...
/* 반복문 종료 */
}
}
컬렉션
public class Calculator {
/* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/
public 반환타입 calculate(...매개변수) {
...
}
...
public void removeResult() {
/* 구현 */
}
}
public class App {
public static void main(String[] args) {
/* Calculator 인스턴스 생성 */
Scanner sc = new Scanner(System.in);
/* 반복문 시작 */
System.out.print("첫 번째 숫자를 입력하세요:");
int num1 = sc.nextInt();
System.out.print("두 번째 숫자를 입력하세요:");
int num2 = sc.nextInt();
System.out.print("사칙연산 기호를 입력하세요: ");
char operator = sc.next().charAt(0);
/* 위 요구사항에 맞게 소스 코드 수정 */
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
...
/* 반복문 종료 */
}
}
public enum OperatorType {
/* 구현 */
}
public class ArithmeticCalculator /* Hint */ {
/* 수정 */
}
제네릭
calculate
)public class ArithmeticCalculator /* Hint */ {
/* 수정 */
}
OperatorType operator;
while (true) {
try {
System.out.println("사칙연산 기호를 입력하세요 (+, -, *, /): ");
char operatorChar = br.readLine().charAt(0);
operator = OperatorType.fromChar(operatorChar);
break;
} catch (IllegalArgumentException e) {
System.out.println("잘못된 연산자입니다. +, -, *, / 중 하나를 입력하세요.");
}
}
public class ArithmeticCalculator<T extends Number> {
public double calculate(T num1, T num2, OperatorType operator) {
double a = num1.doubleValue();
double b = num2.doubleValue();
double result;
switch (operator) {
case ADD -> result = a + b;
case SUBTRACT -> result = a - b;
case MULTIPLY -> result = a * b;
case DIVIDE -> {
if (b == 0) {
throw new ArithmeticException("나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.");
}
result = a / b;
}
default -> throw new IllegalArgumentException("유효하지 않은 연산자입니다.");
}
results.add(result);
return result;
}
}
public List<Double> getResultsGreaterThan(double threshold) {
return results.stream()
.filter(result -> result > threshold)
.collect(Collectors.toList());
}
잘못된 연산자 입력 테스트
입력: &, x, #, (
기대 결과: "잘못된 연산자입니다. +, -, *, / 중 하나를 입력하세요.: " 메시지가 출력되고 다시 입력 요청.
다양한 숫자 타입 처리 테스트
입력: 15.5 + 10.2
기대 결과: 25.7 출력.
결과 필터링 테스트
저장된 결과: [10.0, 15.0, 25.0, 30.0]
입력: threshold = 20.0
기대 결과: [25.0, 30.0]
모든 테스트 시나리오에서 기대한 대로 동작함.
프로그램 비정상 종료 없이 입력 요청을 반복 처리함.
예외 처리
사용자 입력의 예외 처리 로직을 추가하여 프로그램 안정성을 높임.
잘못된 입력에 대해 친화적인 안내 메시지를 제공.
제네릭 설계
코드 확장성이 향상되었으며, 정수와 실수를 모두 처리 가능.
사실 제네릭 까지는 어떻게 할 수 있었으나, 스트림과 더불어 어떻게 잘 코드에 녹여내며 활용할지 고민을 많이 했었습니다.
스트림 활용
조건에 맞는 결과를 효율적으로 필터링하는 기능을 추가.
Exception Handling
예외 발생 가능성이 있는 모든 입력 값에 대해 방어적 코드를 작성해야 한다.
Generic Programming
다양한 숫자 타입을 처리할 수 있도록 설계하면 코드 재사용성과 확장성이 크게 향상됨.
= Lambda & Stream
스트림 API는 조건에 따른 데이터를 처리할 때 간결하고 효과적임.
위의 트러블 슈팅 과정을 통해 잘못된 입력 처리, 다양한 숫자 타입 지원, 결과 필터링 기능을 추가하여 프로그램 안정성과 사용자 경험을 아래와 같이 개선할 수 있었습니다.
앞으로도 확장 가능한 설계를 유지하며 결과물이 좋으며 확장가능하며 유지보수가 용이한 프로젝트로 발전시켜 나가겠습니다.