본문 바로가기

독서찰기(讀書札記)/이펙티브 자바

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

※ API 설계 요령을 설명한다.

 

1. 메서드 이름을 신중히 짓자.

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

2. 편의 메서드를 너무 많이 만들지 말자.

  • 메서드가 너무 많은 클래스는 익히고, 사용하고, 문서화하고, 테스트하고, 유지보수하기 어렵다. (인터페이스도 마찬가지)

3. 매개변수 목록은 짧게 유지하자.

  • 4개 이하가 좋다.
  • 같은 타입의 매개변수 여러 개가 연달아 나오는 경우가 특히 해롭다.
    • 순서를 기억하기 어려울뿐더러, 실수로 순서를 바꿔 입력해도 그대로 컴파일되고 실행된다.
  • 과하게 긴 매개변수 목록을 짧게 줄여주는 기술 세 가지가 있다.
    • 첫 번째, 여러 메서드로 쪼갠다.
      • 쪼개진 메서드 각각은 원래 매개변수 목록의 부분집합을 받는다.
      • 잘못하면 메서드 수가 너무 많아질 수 있지만, 직교성(orthogonality)을 높여 오히려 메서드 수를 줄여주는 효과도 있다.
    • 두 번째, 매개변수 여러 개를 묶어주는 도우미 클래스를 만드는 것이다.
      • 이런 도우미 클래스는 정적 멤버 클래스(아이템24)로 둔다.
      • 특히 잇따른 매개변수 몇 개를 독립된 하나의 개념으로 볼 수 있을 때 추천하는 기법이다.
    • 세 번째, 앞서의 두 기법을 혼합한 것으로, 객체 생성에 사용한 빌더 패턴(아이템2)을 메서드 호출에 응용한다고 보면 된다.
      • 이 기법은 매개변수가 많을 때, 특히 그중 일부는 생략해도 괜찮을 때 도움이 된다.

4. 매개변수의 타입으로는 클래스보다는 인터페이스가 더 낫다. (아이템64)

  • 인터페이스 대신 클래스를 사용하면 클라이언트에게 특정 구현체만 사용하도록 제한하는 꼴이며, 혹시라도 입력 데이터가 다른 형태로 존재한다면 명시한 특정 구현체의 객체로 옮겨 담느라 비싼 복사 비용을 치러야 한다.

5. boolean보다는 원소 2개짜리 열거 타입이 낫다.

  • 메서드 이름상 boolean을 받아야 의미가 더 명확할 때는 예외다.
  • 열거 타입을 사용하면 코드를 읽고 쓰기가 더 쉬워진다.
  • 나중에 선택지를 추가하기도 쉽다.
public enum TemperatureScale { FAHRENHEIT, CELCIUS }
  • 확실히 Thermometer.newInstance(true) 보다는
    Thermometer.newInstance(TemperatureScale.CELCIUS)가 하는 일을 훨씬 명확히 알려준다.
  • 나중에 캘빈 온도도 지원해야 한다면, TemperatureScale 열거 타입에 캘빈온도(KELVIN)를 추가하면 된다.
  • 또한 온도 단위에 대한 의존성을 개별 열거 타입 상수의 메서드 안으로 리팩터링해 넣을 수도 있다. (아이템34)

 

 

※ 소프트웨어 설계 영역에서 "직교성이 높다"라고 하면 "공통점이 없는 기능들이 잘 분리되어 있다." 혹은 "기능을 원자적으로 쪼개 제공한다" 정도로 해석할 수 있다.

 

※ "직교성을 높여 오히려 메서드 수를 줄여주는 효과도 있다"는 말은 무슨 뜻일까? 세상 만물은 결국 100개가 조금 넘는 원소가 결합되어 만들어진다. 마찬가지로 API도 기본 기능만 잘 갖춰놓으면 아무리 복잡한 기능도 조합해낼 수 있다. 기능을 원자적으로 쪼개다 보면, 자연스럽게 중복이 줄고 결합성이 낮아져 코드를 수정하기 수월해진다. 테스트하기 쉬워짐은 물론이다. 일반적으로 직교성이 높은 설계는 가볍고 구현하기 쉽고 유연하고 강력하다.


※ 그렇다고 무한정 작게 나누는 게 능사는 아니다. 직교성이 낮아지더라도 편의 기능으로 제공하는 편이 나을 수도 있다. 이처럼 직교성은 절대적인 가치라기보다는, 철학과 원칙을 가지고 일관되게 적용해야 하는 설계 특성이다.