본문으로 건너뛰기
안동민 개발노트 아이콘

안동민 개발노트

본문 시작
6장 : 메서드

메서드 정의와 호출

메서드는 여러 문장을 이름 붙인 하나의 동작으로 묶습니다.

코드 중복을 줄이는 효과도 있지만 호출자가 구현 세부 사항 대신 입력과 결과의 계약만 보게 하는 것이 더 중요합니다.

반환 타입, 메서드 이름, 매개변수 목록은 호출 가능한 형태를 결정합니다.

void 메서드는 결과값을 돌려주지 않지만 상태를 바꾸거나 출력을 만드는 부작용은 가질 수 있습니다.

이 절에서는 한 메서드가 한 가지 이유로 바뀌도록 경계를 잡습니다.


시그니처가 호출 가능한 모양을 정한다

메서드 이름과 매개변수 타입 목록은 어떤 호출을 받을지 구분합니다.

반환 타입은 호출 결과의 계약이지만 오버로딩을 구분하는 요소는 아닙니다.


매개변수는 입력이고 반환값은 결과다

호출자가 제공해야 하는 값과 메서드가 계산해 돌려주는 값을 분리합니다.

출력만 하고 결과를 반환하지 않으면 다른 코드에서 재사용하기 어려울 수 있습니다.

MethodContract.java는 입력을 받은 계산 메서드와 그 결과를 사용하는 호출부를 분리합니다. 메서드 이름·매개변수·반환 타입을 먼저 읽고 본문을 가린 채도 호출 목적을 설명할 수 있는지 확인해 봅니다.

MethodContract.java
public class MethodContract {
    static int clamp(int value, int minimum, int maximum) {
        if (minimum > maximum) {
            throw new IllegalArgumentException("minimum > maximum");
        }
        return Math.max(minimum, Math.min(value, maximum));
    }

    public static void main(String[] args) {
        System.out.println(clamp(15, 0, 10));
        System.out.println(clamp(-3, 0, 10));
        // clamp(5, 10, 0); // 실행 시 IllegalArgumentException
    }
}

호출부의 인자 순서와 메서드 선언의 매개변수 순서를 대조해 보세요. 반환값을 출력할 수 있다는 것은 메서드가 계산 결과를 외부로 전달했다는 뜻이고, void 메서드는 같은 방식으로 값 자리에 사용할 수 없습니다.

10
0

clamp는 입력 세 개와 정수 결과, 그리고 잘못된 범위에서의 실패 계약을 한곳에 모읍니다.


지역 변수는 호출마다 새로 만들어진다

메서드 안의 지역 변수는 해당 호출의 실행 프레임에 속합니다.

필드가 필요하지 않은 중간 계산을 지역에 두면 호출 사이 상태가 섞이지 않습니다.

같은 메서드를 두 번 호출해도 지역 변수는 호출마다 별도의 공간에 만들어집니다. 한 호출의 중간값이 다음 호출에 남아 있어야 한다면 지역 변수가 아니라 객체 상태나 명시적인 반환값으로 모델링해야 합니다.

비교 1
static boolean isAdult(int age) {
    return age >= 18;
}
비교 2
static void printAdult(int age) {
    System.out.println(isAdult(age)); // 출력 부작용과 계산을 분리
}
비교 3
// int result = printAdult(20); // 컴파일 오류: void는 값이 아님

메서드 이름은 구현보다 의도를 말한다

process처럼 넓은 이름보다 calculateTotal, isValidAge처럼 결과를 설명하는 이름이 좋습니다.

이름과 실제 부작용이 어긋나지 않아야 합니다.

calculate(int, int)보다 calculateDiscountedPrice(int price, int discountRate)가 호출 이유와 단위를 더 잘 드러냅니다. 구현이 한 줄이어도 이름이 문제의 동사를 말하게 하면 호출자는 계산식을 다시 읽지 않아도 됩니다.


메서드 추출은 줄 수를 줄이는 작업이 아니라 입력, 결과, 부작용의 경계를 이름으로 고정하는 작업입니다.