메서드: 코드 중복을 줄이고 책임 나누기
9강. 메서드: 코드 중복을 줄이고 책임 나누기
1. 이번 강의에서 해결할 문제
main에 입력, 평균 계산, 최고 점수 검색, 출력을 모두 넣으면 같은 계산을 다른 화면에서 재사용하기 어렵고 오류가 난 위치도 찾기 힘듭니다. 코드를 단순히 여러 조각으로 자르는 것이 아니라, 입력과 반환값이 분명한 한 가지 책임으로 나누어야 합니다.
2. 학습 목표
3. 핵심 개념
메서드는 객체나 클래스에 속한 이름 있는 작업입니다
Java의 메서드는 이름, 매개변수 타입, 반환 타입으로 호출자와의 계약을 표현합니다.
static int addBonus(int score) {
int result = score + 50;
return result;
}
| 부분 | 의미 |
|---|---|
static | 이번 예제에서는 객체를 만들지 않고 main에서 호출할 수 있게 합니다. 객체 메서드는 클래스 강의에서 다룹니다. |
int | 호출이 끝나면 정수 하나를 반환한다는 계약입니다. |
addBonus | 호출할 작업 이름입니다. 동작을 드러내는 동사형 이름을 씁니다. |
int score | 정수 인자를 받을 매개변수입니다. |
return result | 계산 결과를 호출 위치로 돌려주고 메서드를 끝냅니다. |
호출할 때 전달하는 실제 값은 인자입니다. addBonus(120)에서 120은 인자이고, 메서드 안에서는 매개변수 score가 그 값을 받습니다.
반환과 출력은 목적이 다릅니다
System.out.println()은 사람이 콘솔에서 값을 보게 하지만 다른 계산에 결과를 전달하지 않습니다. return은 호출자가 값을 저장하거나 다른 메서드에 전달하게 합니다. 계산 메서드는 결과를 반환하고, 어느 화면에 표시할지는 호출자가 정하면 재사용과 테스트가 쉬워집니다. void는 호출자에게 돌려주는 값이 없다는 뜻입니다.
한 가지 책임은 변경 이유로 판단합니다
평균 규칙 변경과 출력 형식 변경은 서로 다른 이유로 발생합니다. 따라서 average()는 계산만, main 또는 별도 출력 메서드는 표시만 담당하는 편이 좋습니다. 반대로 평균을 구하는 덧셈과 나눗셈을 의미 없이 각각 메서드로 만들 필요는 없습니다.
메서드 경계에서 잘못된 입력을 막습니다
평균 메서드는 빈 배열을 받으면 0으로 나눌 수 없습니다. 최고 점수 메서드는 첫 요소를 읽기 때문에 빈 배열에서 인덱스 오류가 납니다. 메서드 시작에서 요구 조건을 확인하면 더 가까운 위치에서 뜻이 분명한 오류를 낼 수 있습니다.
4. 가장 작은 예제로 시작하기
static int addBonus(int score) {
return score + 50;
}
public static void main(String[] args) {
int finalScore = addBonus(120);
System.out.println(finalScore);
}
- 프로그램은
main에서addBonus(120)을 만납니다. - 인자
120이 매개변수score에 전달됩니다. - 메서드는
120 + 50을 계산해170을 반환합니다. - 반환값이
finalScore에 저장되고170이 출력됩니다.
호출을 addBonus(200)으로 바꾸면 메서드 코드는 그대로이고 결과만 250으로 달라집니다.
5. 코드 한 줄씩 이해하기와 실행 흐름
src/RecordFunctions.java 작성
실행 환경: 코드 편집기
실행 위치: C:\dev\game-records
실행 전 확인: 같은 이름의 기존 파일이 있다면 덮어쓰기 전에 Git diff와 이번 강의 변경 범위를 확인합니다.
대상 파일: src/RecordFunctions.java
public class RecordFunctions {
static double average(int[] scores) {
if (scores.length == 0) {
throw new IllegalArgumentException("점수가 비었습니다.");
}
int total = 0;
for (int score : scores) {
total += score;
}
return (double) total / scores.length;
}
static int highest(int[] scores) {
if (scores.length == 0) {
throw new IllegalArgumentException("점수가 비었습니다.");
}
int result = scores[0];
for (int score : scores) {
if (score > result) {
result = score;
}
}
return result;
}
public static void main(String[] args) {
int[] scores = {800, 1200, 950};
System.out.println("평균: " + average(scores));
System.out.println("최고: " + highest(scores));
}
}
PowerShell에서 컴파일·실행
실행 환경: Windows PowerShell
실행 위치: C:\dev\game-records
실행 전 확인: java -version과 javac -version이 선택한 LTS JDK를 가리키고, 소스 파일명이 public 클래스명과 일치하는지 확인합니다.
대상: 이 강의의 .java 파일, out의 class 파일과 명시된 출력 파일
Set-Location C:\dev\game-records
javac -d out .\src\RecordFunctions.java
java -cp out RecordFunctions
예상 출력:
평균: 983.3333333333334
최고: 1200
average(scores)의 데이터 흐름은 다음과 같습니다.
| 반복 | 현재 score | 계산 후 total |
|---|---|---|
| 시작 | - | 0 |
| 1 | 800 | 800 |
| 2 | 1200 | 2000 |
| 3 | 950 | 2950 |
마지막에 (double) total / scores.length를 계산하므로 2950 / 3의 소수 부분이 보존됩니다. highest()는 첫 점수 800을 현재 최고값으로 시작하고, 더 큰 값을 만날 때만 result를 바꾸어 1,200을 반환합니다.
배열 변수의 참조가 매개변수로 전달되지만 두 계산 메서드는 배열 요소를 변경하지 않습니다. 각 호출의 total, result, 반복 변수 score는 해당 메서드 안에서만 존재하는 지역 변수입니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
10. 다음 강의 연결
점수 배열의 계산 책임을 메서드로 나눴습니다. 다음 강의에서는 문자열을 불변 객체로 다루고, 여러 문자열 조각을 반복해 연결할 때 StringBuilder가 필요한 이유를 살펴봅니다.
메서드: 코드 중복을 줄이고 책임 나누기 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.