Java

[Effective Java] 아이템 51 : 메서드 시그니처를 신중히 설계하라(feat. 팀 컨벤션)

jwKim96 2023. 2. 21. 01:17

0. 들어가며

이번 아이템을 살짝 훑어보면, 좋은 메서드를 만들기 위한 규칙을 설명합니다.

먼저 규칙들을 설명하기에 앞서, 규칙들을 왜 제안하는지 생각해봤습니다.

  1. 일관성 없는 메서드명
  2. 메서드가 너무 많아서 뭘 써야할 지 모르는 상황
  3. 매개변수가 너무 많아서 헷갈리는 상황

대표적으로 이런 경우들로 생각해볼 수 있고, 아마 다들 한번쯤은 겪어보셨을 것이라 생각합니다.

이제 필자가 어떤 규칙들을 제안하고, 그 규칙들을 지키면 위와 같은 상황을 해결할 수 있는지 살펴보겠습니다.

1. 메서드 시그니처 규칙

필자가 제안한 메서드 시그니처 규칙은 다음과 같습니다.

  • 메서드 이름을 신중히 짓자
    • 표준 명명 규칙(아이템68)을 따르자
    • 같은 패키지 속의 다른 이름들과 일관되게 짓자
    • 개발자 커뮤니티에서 널리 받아들여지는 이름을 사용하자
    • 너무 긴 이름은 피하자
  • 편의 메서드를 너무 많이 만들지 말자
    • 메서드가 너무 많은 인터페이스는 사용하기도, 구현하기도 힘듦
    • ‘확신이 서지 않으면 만들지 말자’
  • 매개변수 목록은 짧게 유지하자
    • 4개가 넘어가는 순간 헷갈리기 쉬움
    • ‘같은 타입이 연속해서 나오는 경우는 아주 안좋음’
    • 이러한 문제를 해결하는 기술
      1. 여러 메서드로 쪼개기
      2. 매개변수 여러개를 묶는 클래스
      3. 빌더 패턴 사용
  • 매개변수 타입으로는 인터페이스가 더 나음(아이템 68)
  • boolean 보다는 원소 2개짜리 열거 타입이 더 나음

하지만 저는 이 보다 더 중요한 것이 있다고 생각하는데요.

그건 바로 내가 일하고있는 팀의 컨벤션 입니다.

2. 팀 컨벤션

저는 백엔드 개발자로 취업하여 2주 정도 일한 상태인데요.

적응 중이라 그런지 동료분들이 리뷰 해주실 때, 많이 알려주시는것 중 하나가 컨벤션 관련 내용입니다.

컨벤션을 유지하는 이유는 형식을 비슷하게 유지하면 코드를 읽을때 피로가 덜하고 가독성이 좋기 때문입니다.

그래서 제 경험을 바탕으로 어떤 부분들을 중점적으로 파악하면 좋을지 정리해봤습니다.

2.1 메서드명

메서드명은 보통 자주 쓰는 단어들을 많이 쓰게되니, 컨벤션을 딱 맞추지 않아도 됩니다.

하지만, 미묘하게 스타일이나 사용하는 단어가 다르기도 합니다.

길게 풀어쓰는 스타일 vs 짧고 제너럴한 단어로 표현하는 스타일

// 이렇게 길게 풀어쓰는사람이 있는가 하면
class Order {
    public static Order createOrderWithMenu(Menu menu) { ... }
}

// 이렇게 이펙티브 자바에서 제안하는 팩터리 메서드 방식으로 작성하기도 함
class Order {
    public static Order from(Menu menu) { ... }
}

영어 문장같은 메서드명 vs 가독성 좋은 짧고 간단한 단어

// 메서드의 동작을 영어로 풀어서 작성 하는가 하면
class ReviewService {
    public boolean isPossibleToCreateReview(Review review) { ... }
}

// 심플한 단어로 표현하기도 함
class ReviewService {
    public boolean canCreateReview(Review review) { ... }
}

메서드의 앞에 vs 메서드의 뒤에(boolean 반환 vs 예외 터트리기)

// isValid 라고 명명하고 boolean 을 반환하도록 구현하거나
class Something {
    public boolean isValidSomething() { ... }
}

// 검증하여 메서드 자체에서 예외를 발생시키기도 함
class Something {
    public void somethingValidation() { ... }
}

이 외에도 상황에 따라 컨벤션에 따라 다양한 단어들을 선택해서 사용합니다.

  • find~ vs get~
  • create~ vs get~
  • sort vs orderBy

등등..

2.2 파라미터

파라미터는 보통 개수에 따라 어떻게 달라지는지 확인해볼 수 있습니다.

적당한 파라미터는 괜찮 vs DTO 조아

// 이렇게 4개 정도는 그냥 쓰는가 하면
class Something {
    public void doSomething(int num, String str, char chr, boolean isReal) { ... }
}

// 2개 이상만 되도 DTO 로 만드는 사람도 있음
class Something {
    public void doSomething(Dto dto) { ... }
}

record Dto(int num, String str) { }

왼쪽에서 오른쪽으로 vs 위에서 아래로

// 끝을 모르게 쭉쭉 붙이는 사람이 있는가 하면
class Something {
    public void doSomething(int num, String str, char chr, boolean isReal, long howLong, short howShort) { ... }
}

// 이렇게 세로로 쭉 내려 쓰느 사람도 있음
class Something {
    public void doSomething(
        int num, 
        String str, 
        char chr, 
        boolean isReal, 
        long howLong, 
        short howShort
    ) { 
    // 구현부 ... 
    }
}

// 그리고 이렇게 첫번째 인자 이후로만 내려쓰는 경우도 있음
class Something {
    public void doSomething(int num, 
                            String str, 
                            char chr, 
                            boolean isReal, 
                            long howLong, 
                            short howShort) {
    // 구현부 ...
    }
}        

위 예제의 3번째 경우는 회사에서 동료분이 쓰시는 스타일을 보고 배웠는데요.

2번째는 구현부와 들여쓰기가 같아 한눈에 들어오지 않을 수 있는데요.

3번째는 구현부와 들여쓰기 차이가 있기 때문에 파라미터 선언과 구현부가 확실히 구분된다는 장점이 있습니다.

이 외에도 다음과 같은 고려사항이 있을 수 있겠네요!

  • Wrapper type 사용 여부
  • Primitive type을 앞에 vs Reference type 을 앞에

등등