JAVA/Effective Java

[아이템 51] 메서드 시그니처를 신중히 설계하라

꾸준함. 2024. 3. 9. 23:01

메서드 시그니처

메서드 시그니처(Method Signature)는 메서드의 선언 부분에서 메서드의 식별을 정의하는 부분을 의미합니다.

메서드 시그니처에는 메서드의 이름, 매개변수의 타입, 반환 값의 타입이 포함됩니다.

일반적으로 메서드 시그니처는 다음과 같은 형식을 가집니다

 

 

 

형식 부연 설명

  • returnType: 메서드가 반환하는 값의 데이터 타입을 나타내며  만약 메서드가 반환하는 값이 없으면 void라고 표시
  • methodName: 메서드의 이름을 나타냄
  • parameterType1, parameterType2, ...: 메서드가 받는 매개변수의 데이터 타입
  • param1, param2, ...: 메서드가 받는 실제 매개변수의 이름

 

여기서 returnType, methodName, 그리고 parameterType의 조합과 순서가 모두 일치할 경우 같은 메서드 시그니처를 가진다고 합니다.

  • 매개변수 타입이 일치할 경우 매개변수명은 달라도 같은 메서드 시그니처가 같다고 간주

 

 

 

메서드 이름은 신중히 지어야 함

메서드명은 항상 이후 아이템 68에 정리할 표준 명명 규칙을 따라야 합니다.

  • 항상 이해할 수 있고 같은 패키지에 속한 다른 이름들과 일관되게 짓는 것이 최우선 목표
  • 그다음 목표는 개발자 커뮤니티에서 널리 받아들여지는 이름을 사용하는 것
  • 긴 이름을 피하고 애매하면 자바 라이브러리의 API 가이드를 참조

 

자바 메서드 명명 규칙

 

Java에서는 메서드 명명에 대한 몇 가지 규칙이 있습니다.

이러한 규칙은 코드의 가독성을 향상하고 일관성을 유지하기 위한 것입니다. 아래는 Java 메서드 명명 규칙의 일반적인 가이드라인입니다

  1. 카멜 케이스 (Camel Case): 메서드 이름은 카멜 케이스를 따라야 하며 카멜 케이스는 첫 단어는 소문자로 시작하고, 그 이후의 각 단어는 대문자로 시작하는 방식을 의미
  2. 동사 사용: 메서드 이름은 주로 해당 메서드가 수행하는 동작이나 행동을 나타내는 동사로 시작하는 것이 좋음
  3. 명확하고 간결하게: 메서드의 이름은 명확하고 간결해야 하며 다른 개발자가 메서드 이름만으로도 해당 메서드가 무엇을 하는지 이해할 수 있도록 작성
  4. 의미 있는 이름: 메서드의 이름은 해당 메서드가 하는 일을 명확하게 나타내야 하며 가능한 한 추상적이거나 일반적인 이름은 피해야 함
  5. get/set 프리픽스 사용: 접근자 (getter) 및 설정자 (setter) 메서드의 이름은 해당 필드의 이름과 일치하도록 하며, 각각 get 및 set 접두어를 사용
  6. Boolean 반환 값의 경우 is 프리픽스 사용: 메서드가 불린 값을 반환하는 경우, 일반적으로 is 접두어를 사용하여 해당 속성이나 조건을 나타냄
  7. JavaBeans 규약 준수: JavaBeans 규약에 따르면 프로퍼티에 대한 getter와 setter 메서드를 특정한 규칙에 따라 작성해야 함
    1. Getter 메서드:
      • 메서드 이름은 "get" 뒤에 속성의 이름이 옴
      • 메서드는 매개변수가 없어야 합니다.
      • 메서드의 반환 타입은 속성의 데이터 타입과 일치
      • ex) public int getItemCount() { ... }
    2. Setter 메서드:
      • 메서드 이름은 "set" 뒤에 속성의 이름이 옴
      • 메서드는 하나의 매개변수를 가져야 하며 이 매개변수는 속성의 새로운 값
      • 메서드의 반환 타입은 보통 void
      • ex) public void setItemCount(int itemCount) { ... }

 

편의 메서드를 너무 많이 만들지 말아야 함

자바에서 "편의 메서드"는 주로 개발자가 더 쉽게 코드를 작성하고 사용할 수 있도록 돕기 위해 제공되는 메서드를 의미합니다.

 

1. 편의 메서드 장점

이러한 편의 메서드들은 자주 사용되는 일반적인 작업을 단순화하거나 추상화하여 코드의 가독성을 높이고 개발자의 생산성을 향상합니다.

다양한 클래스와 라이브러리에서 편의 메서드가 제공됩니다.

 

문자열 관련 편의 메서드

  • isEmpty()
  • trim().
  • toUpperCase()
  • toLowerCase()

 

Collection 관련 편의 메서드

  • addAll(Collection<? extends E> c)
  • sort(Comparator<? super E> c)

 

편의 메서드는 특정 작업을 수행하기 위한 표준적이고 간편한 방법을 제공하므로, 이를 적절히 활용하면 코드를 간소화하고 가독성을 향상할 수 있습니다.

개발자들은 자주 사용되는 기능들을 단순화하는 편의 메서드를 찾고 활용하는 것이 좋습니다.

 
2. 편의 메서드 단점
다만, 편의 메서드를 지나치게 만들어 메서드가 너무 많은 클래스의 경우 다음과 같은 측면에서 어려움이 생겨 사용하기 어렵습니다.
  • 문서화
  • 테스트
  • 유지보수

 

매개변수 목록은 짧게 유지해야 함

저자는 메서드의 매개변수 개수를 최대 4개까지로 제한하는 것을 권장하며 특히 같은 타입의 매개변수가 여러 개 연이어 나올 경우, 휴먼 에러 발생 확률이 증가한다고 강조하고 있습니다.

  • 사용자가 매개변수 순서를 기억하기 어려울 뿐더러, 실수로 순서를 바꿔 입력해도 그대로 컴파일되고 실행
  • 이로 인해 의도와 다르게 동작할 확률이 올라감

 

이 때문에 매개변수 목록을 짧게 줄여야 하고 책에서는 다음과 같은 기술을 소개합니다.

  • 메서드 쪼개기
  • 도우미 클래스
  • 빌더 패턴을 메서드 호출에 응용

 

1. 메서드 쪼개기

 

첫 번째 방법은 여러 메서드로 쪼개는 것입니다.

쪼개진 메서드 각각은 원래 매개변수 목록의 부분지합을 받습니다.

이 방법을 적용하면 메서드가 너무 많아질 수 있지만 직교성을 높여 오리혀 메서드 수를 줄여주는 효과도 있습니다.

  • "직교성을 높인다"는 표현은 특정 기능이나 역할을 수행하는 코드 요소들이 서로 독립적이고 간섭하지 않는 상태
  • 직교성이 높으면 유지보수가 용이해지고 코드 재사용성이 증가됨

 

위 방법을 잘 적용한 예시로 java.util.List 인터페이스가 있습니다.

리스트에서 주어진 원소의 인덱스를 찾아야 하는데, 저체 리스트가 아니라 지정된 범위의 부분 리스트에서의 인덱스를 찾는다고 가정했을 때 하나의 메서드로 구현하기 위해서는 `부분 리스트의 시작`, `부분 리스트의 끝`, 그리고 `찾을 원소`까지 3개의 매개변수가 필요합니다.

하지만 List는 부분리스트를 반환하는 subList 메서드와 주어진 원소의 인덱스를 알려주는 indexOf 메서드를 별도 제공하고 subList가 반환한 부분리스트 역시 완벽한 List이므로 두 메서드를 조합하면 원하는 목적을 달성할 수 있습니다.

 

 

2. 도우미 클래스

 

두 번째 방법은 매개변수 여러 개를 묶어주는 도우미 클래스를 만드는 것입니다.

일반적으로 이런 도우미 클래스는 정적 멤버 클래스로 생성하고 특히 잇따른 매개변수 몇 개를 독립된 하나의 개념으로 볼 수 있을 때 추천하는 기법입니다.

 

 

3. 빌더 패턴을 메서드 호출에 응용

 

세 번째 방법은 앞서의 두 기법을 혼합한 것으로, 객체 생성에 사용한 빌더 패턴을 메서드 호출에 응용하는 것입니다.

이 기법은 매개변수가 많을 때, 특히 그중 일부를 생략해도 무방할 때 도움이 됩니다.


 

비고

 

1. 매개변수의 타입으로는 클래스보다는 인터페이스를 권장

 

  • 인터페이스 대신 구현체를 매개변수 타입으로 설정하는 경우 메서드를 사용하는 클라이언트에게 특정 구현체만 사용하도록 제한하는 꼴
  • 인터페이스 사용 시 추후에 구현될 구현체도 넘길 수 있어 유연함

 

 

 

2. 매개변수의 타입으로 boolean보다는 원소 2개짜리 열거 타입을 권장

 

  • 열거  타입을 사용하면 코드를 읽고 쓰기가 더 쉬워짐
  • 나중에 선택지를 추가하기도 쉬움

 

 

참고

이펙티브 자바

반응형