| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- 자바
- 빌더 패턴
- 백엔드
- 프록시 패턴
- 스프링 배치
- 추상클래스
- 디자인 패턴
- 스프링
- redis
- 프로그래머스
- lv1
- 코드카타
- 토스
- 계산기
- 템플릿 메서드 패턴
- Spring Batch
- 로드밸런서
- java
- 트러블슈팅
- 스케줄러
- spring boot
- 이펙티브 자바
- Spring
- Effective Java
- 배치
- GoF 23
- Til
- 김영한
- DB
- 성능 개선
Archives
- Today
- Total
김코딩
계산기 Lv.1 본문
오늘은 자바를 공부하면서 만들어본 간단한 계산기 예제를 소개하려고 합니다.
이 예제는 총 3단계(Lv1~Lv3)로 나누어져 있으며, 자바 언어에 조금씩 익숙해지는 데 도움이 되었습니다.
이번에는 Lv 1 단계의 요구사항과 구현 흐름을 정리해보았습니다.
Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기
- 양의 정수(0 포함)를 입력받기
- Scanner를 사용하여 양의 정수 2개(0 포함)를 전달 받을 수 있습니다.
- 양의 정수는 각각 하나씩 전달 받습니다.
- 양의 정수는 적합한 타입으로 선언한 변수에 저장합니다.
- 사칙연산 기호(➕,➖,✖️,➗)를 입력받기
- Scanner를 사용하여 사칙연산 기호를 전달 받을 수 있습니다.
- 사칙연산 기호를 적합한 타입으로 선언한 변수에 저장합니다. (charAt(0))
- 위에서 입력받은 양의 정수 2개와 사칙연산 기호를 사용하여 연산을 진행한 후 결과값을 출력하기
- 키워드 : if switch
- 사칙연산 기호에 맞는 연산자를 사용하여 연산을 진행합니다.
- 입력받은 연산 기호를 구분하기 위해 제어문을 사용합니다. (예를 들면 if, switch)
- 연산 오류가 발생할 경우 해당 오류에 대한 내용을 정제하여 출력합니다.
- ex) “나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.“
- 반복문을 사용하되, 반복의 종료를 알려주는 “exit” 문자열을 입력하기 전까지 무한으로 계산을 진행할 수 있도록 소스 코드를 수정하기
- 키워드 : 무한으로 반복, 수정하기 (처음부터 무한 반복하는 것이 아니라, 위 스텝별로 진행하며 수정)
- 반복문을 사용합니다. (예를 들어, for, while…)
요구사항 세부 정리
- 1. 양의 정수 입력
- Scanner를 사용하여 두 개의 양의 정수를 입력받습니다.
- 정수가 아닌 값이 입력되면 InputMismatchException 예외를 처리합니다.
- 문자열을 입력받고 charAt(0)을 이용해 문자로 추출합니다.
- 사용 가능한 연산자: +, -, *, /
- if 문을 이용해 연산자에 따라 분기 처리
- / 연산 시 분모가 0인지 검사
- while 문으로 전체 계산을 감싸고, "exit"이 입력되면 종료
리팩토링 전 코드
package lv1;
import java.util.InputMismatchException;
import java.util.Scanner;
public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
int num1 = 0;
while (true) {
System.out.print("첫 번째 숫자를 입력하세요: ");
try {
num1 = sc.nextInt();
if (num1 < 0) {
System.out.println("0 이상의 정수만 입력 가능합니다.");
continue;
}
break;
} catch (InputMismatchException e) {
System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
sc.nextLine();
}
}
int num2 = 0;
while (true) {
System.out.print("두 번째 숫자를 입력하세요: ");
try {
num2 = sc.nextInt();
if (num2 < 0) {
System.out.println("0 이상의 정수만 입력 가능합니다.");
continue;
}
break;
} catch (InputMismatchException e) {
System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
sc.nextLine();
}
}
sc.nextLine();
System.out.print("사칙연산 기호를 입력하세요(예: +,-,*,/) : ");
char operator = sc.nextLine().charAt(0);
double result = 0.0;
if (operator == '+') {
result = num1 + num2;
} else if (operator == '-') {
result = num1 - num2;
} else if (operator == '*') {
result = num1 * num2;
} else if (operator == '/') {
if (num2 == 0) {
System.out.println("나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.");
continue;
} else {
result = (double) num1 / num2;
}
} else {
System.out.println("올바른 연산자를 입력해주세요.");
}
System.out.println("결과: " + result);
System.out.print("더 계산하시겠습니까? (exit 입력 시 종료): ");
String order = sc.nextLine();
if (order.equals("exit")) {
System.out.println("계산기를 종료합니다. 안녕히 가세요");
break;
}
}
}
구현 설명
- num1과 num2에 숫자를 받습니다. (숫자 이외의 문자가 들어오면 InputMismatchException이 터지기 때문에 숫자만 받을 수 있도록 예외처리를 해놓았습니다)
- operator 문자에 연산기호를 입력합니다.
- 연산 결과는 나눗셈을 한다는 가정하에 소숫점이 나올 수 있기 때문에 result 변수를 int형 말고 double형으로 선언해주었습니다.
- 이제 if문을 사용하여 각 연산자에 맞는 연산을 진행하도록 합니다. 하지만 나눗셈 연산이 들어왔을 때에는 분모가 0일때를 고려하여 조건을 다시 넣어주었습니다. 이때 분모에 0이 들어올 시 continue문을 사용하여 다시 while문이 돌아가게 만들었습니다.
- 연산이 종료되면 결과가 나옵니다
- 만약에 연산 종료 후 사용자가 exit을 입력하게 되면 break를 사용하여 while문을 빠져나와 프로그램이 종료되게 됩니다.
리팩토링 후 코드
package lv1;
import java.util.InputMismatchException;
import java.util.Scanner;
public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
// 첫 번째 숫자 입력 : 정수를 입력 받기 위한 스캐너 변수와 메시지를 매개변수로 받습니다.
int num1 = inputNumber(sc, "첫 번째 숫자를 입력하세요: ");
// 두 번째 숫자 입력
int num2 = inputNumber(sc, "두 번째 숫자를 입d력하세요: ");
// 연산자 입력
char operator = getOperator(sc);
// 연산자에 맞는 연산 수행
double result = 0.0;
if (operator == '+') {
result = add(num1, num2);
} else if (operator == '-') {
result = subtract(num1, num2);
} else if (operator == '*') {
result = multiply(num1, num2);
} else if (operator == '/') {
if (num2 == 0) {
System.out.println("나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.");
continue;
} else {
result = (double) num1 / num2;
}
} else {
System.out.println("올바른 연산자를 입력해주세요.");
continue;
}
// 연산 결과 출력
System.out.println("결과: " + result);
// if 문을 도입하여 exit 입력 시 프로그램 종료
System.out.print("더 계산하시겠습니까? (exit 입력 시 종료): ");
String order = sc.nextLine();
if (order.equals("exit")) {
System.out.println("계산기를 종료합니다. 안녕히 가세요");
break;
}
}
}
private static double multiply(int num1, int num2) {
double result;
result = num1 * num2;
return result;
}
private static double subtract(int num1, int num2) {
double result;
result = num1 - num2;
return result;
}
private static double add(int num1, int num2) {
double result;
result = num1 + num2;
return result;
}
private static char getOperator(Scanner sc) {
System.out.print("사칙연산 기호를 입력하세요(예: +,-,*,/) : ");
return sc.nextLine().charAt(0);
}
private static int inputNumber(Scanner sc, String message) {
while (true) {
System.out.print(message);
try {
int num = sc.nextInt();
if (num < 0) {
System.out.println("0 이상의 정수만 입력 가능합니다.");
continue;
}
sc.nextLine();
return num;
} catch (InputMismatchException e) {
System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
sc.nextLine();
}
}
}
}
구현 설명
1. inputNumber() 메서드로 숫자 입력 로직 분리
// 첫 번째 숫자 입력 : 정수를 입력 받기 위한 스캐너 변수와 메시지를 매개변수로 받습니다.
int num1 = inputNumber(sc, "첫 번째 숫자를 입력하세요: ");
// 두 번째 숫자 입력
int num2 = inputNumber(sc, "두 번째 숫자를 입력하세요: ");
private static int inputNumber(Scanner sc, String message) {
while (true) {
System.out.print(message);
try {
int num = sc.nextInt();
if (num < 0) {
System.out.println("0 이상의 정수만 입력 가능합니다.");
continue;
}
sc.nextLine();
return num;
} catch (InputMismatchException e) {
System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
sc.nextLine();
}
}
}
- 반복되는 정수 입력 로직을 하나의 메서드로 묶어 중복을 제거했습니다.
- 메시지를 매개변수로 받아서 첫 번째/두 번째 입력에 모두 사용할 수 있습니다.
- 음수 입력 시 안내 메시지를 출력하고 다시 입력을 유도합니다.
- 숫자가 아닌 문자가 들어올 경우 InputMismatchException을 처리합니다.
2. getOperator() 메서드로 연산자 입력 분리
char operator = getOperator(sc);
private static char getOperator(Scanner sc) {
System.out.print("사칙연산 기호를 입력하세요(예: +,-,*,/) : ");
return sc.nextLine().charAt(0);
}
- 연산자 입력은 문자열로 받아 charAt(0)을 통해 문자로 변환합니다.
3. 사칙연산 별로 add(), subtract(), multiply() 메서드로 분리
if (operator == '+') {
result = add(num1, num2);
} else if (operator == '-') {
result = subtract(num1, num2);
} else if (operator == '*') {
result = multiply(num1, num2);
}
private static double add(int num1, int num2) {
double result;
result = num1 + num2;
return result;
}
private static double subtract(int num1, int num2) {
double result;
result = num1 - num2;
return result;
}
private static double multiply(int num1, int num2) {
double result;
result = num1 * num2;
return result;
}
- 각각의 연산을 별도의 메서드로 나누어 코드의 의도를 더 명확히 표현했습니다.
- 나중에 클래스 단위로 리팩토링하거나 테스트하기에도 수월해집니다.
다음 단계에서는 이 로직을 기반으로 Calculator 클래스를 만들어 기능을 분리하는 Lv 2 단계로 넘어갈 예정입니다.
https://github.com/SexyDoGyun/Calculator
GitHub - SexyDoGyun/Calculator
Contribute to SexyDoGyun/Calculator development by creating an account on GitHub.
github.com