mooncommit 2026. 3. 23.
오늘은 저번 시간에 만든 계산기(Step1)를 리팩토링해서 클래스를 분리하고, getter/setter를 적용한 구조화된 계산기를 만들었다.
이번엔 튜터님의 도움 없이 직접 문제를 해결해보는 것이 목표였다.
Step1 vs Step2, 뭐가 달라졌나?
Step1에서는 Main 클래스 하나에 모든 로직이 담겨 있었다. 계산 로직, 입력 처리, 반복 제어가 전부 한 곳에 섞여 있었는데,
이번 Step2에서는 계산 로직을 Calculator 클래스로 분리했다.
| Step1 | Step2 | |
| 구조 | 클래스 1개 | App + Calculator 분리 |
| 계산 방식 | Main 안에서 직접 처리 | Calculator 메서드 호출 |
| 결과 저장 | 없음 | ArrayList로 저장 |
Step 2. 코드 구현
App.java (메인 흐름 담당)
package calculator;
import java.util.Scanner;
public class App {
static void main() {
Calculator calculator = new Calculator();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("첫 번째 양의 정수를 입력해보세요 : ");
int number1 = scanner.nextInt();
if (number1 < 0) {
System.out.println("양의 정수를 입력하세요");
continue;
}
System.out.print("두 번째 양의 정수를 입력해보세요 : ");
int number2 = scanner.nextInt();
if (number2 < 0) {
System.out.println("양의 정수를 입력하세요");
continue;
}
System.out.print("사칙연산 기호를 입력하세요 : ");
char operator = scanner.next().charAt(0);
if (number2 == 0 && operator == '/') {
System.out.println("0으로 나눌수가 없습니다.");
continue;
}
int result = calculator.calculator(number1, number2, operator);
System.out.println("결과: " + result);
scanner.nextLine();
System.out.println("exit를 입력하면 프로그램을 종료하겠습니다.");
System.out.print("계속 진행하시려면 아무거나 입력해주세요 : ");
String exit = scanner.nextLine();
if (exit.equals("exit")) {
System.out.println("프로그램을 종료합니다.");
break;
}
}
}
}
Calculator.java (계산 로직 담당)
package calculator;
import java.util.ArrayList;
public class Calculator {
private ArrayList<Integer> results = new ArrayList<>();
public int calculator(int number1, int number2, char operator) {
int result = 0;
if (operator == '+') result = number1 + number2;
else if (operator == '-') result = number1 - number2;
else if (operator == '*') result = number1 * number2;
else if (operator == '/') result = number1 / number2;
return result;
}
public ArrayList<Integer> getResults() {
return results;
}
public void setResults() {
this.results = results;
}
public void removeResult() {
results.remove(0);
}
}
Step 3. 핵심 학습 포인트
1. 클래스 분리 (단일 책임 원칙)
Step1에서는 Main 하나가 모든 걸 다 했다면, Step2에서는 역할을 나눴다.
- App → 사용자 입력/출력, 흐름 제어
- Calculator → 계산 로직만 담당
이렇게 분리하면 나중에 계산 방식이 바뀌어도 Calculator만 수정하면 된다. App은 손댈 필요가 없다.
"이게 클래스를 분리하는 이유!"
2. getter / setter
Calculator 클래스의 results 필드는 private으로 선언했다. 외부에서 직접 접근하지 못하게 막고, getResults()로만 조회할 수 있게 한 것이다.
private ArrayList<Integer> results = new ArrayList<>();
public ArrayList<Integer> getResults() {
return results; // 조회만 허용
}
getter = 내 정보를 조회하는 기능 setter = 내 정보를 수정하는 기능
Step 4. 어려웠던 점
calculator 메서드를 호출하는 타이밍을 잘못 잡았다. 처음엔 0으로 나누기 체크 이후에 메서드를 호출해야 하는데, 이전에 호출해버려서 예외가 터졌다. 순서가 중요하다는 걸 다시 한번 느꼈다.
느낀 점
이번엔 튜터님 도움 없이 혼자 해보려 했는데, 생각보다 막막한 부분이 있어서 팀원의 도움을 받았다. 덕분에 더 빠르게 구현할 수 있었고,
혼자였다면 훨씬 오래 걸렸을 것 같다.
getter/setter도 그냥 형식적으로 쓰는 게 아니라, 데이터를 보호하는 의도가 있다는 걸 이번에 제대로 이해했다.
다음에는 팀원 도움 없이도 스스로 구현할 수 있도록 여러 번 반복해볼 예정이다. 반복이 답인 것 같다. 😎