Java/Effective Java 3E

[이펙티브자바 3판] ITEM51. 메서드 시그니처를 신중히 설계하라

잭피 2020. 12. 27. 18:14

이번장의 핵심은...

API 설계 요청 5가지를 알아봅시다


API 설계 요령

메서드 이름을 신중히 짓자

1. 표준 명명 규칙을 따릅시다

2. 이해할 수 있고, 같은 패키지에 속한 다른 이름들과 일관되게 짓습니다

3. 개발자 커뮤니티에서 널리 받아들여지는 이름을 사용합시다

4. 긴 이름은 피합시다

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

1. 모든 메서드는 각각 자신의 소임을 다하도록 합니다

2. 메서드가 많은 클래스는 익히고, 사용하고, 문서화하고, 테스트하고, 유지보수하기 어렵습니다

→ 인터페이스도 마찬가지입니다

3. 확신이 서지 않으면 만들지 말아야 합니다

 

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

1. 4개 이하가 좋습니다 (4개가 넘어가면 매개변수를 전부 기억하기가 쉽지 않습니다)

2. 같은 타입의 매개변수 여러 개가 연달아 나오는 경우가 특히 해습니다

→ 사용자가 매개변수 순서를 기억하기 어렵고, 실수로 순서를 바꿔입력할 수 있습니다

과하게 긴 매개변수 목록을 짧게 줄여주는 기술

1. 여러 메서드로 쪼갭니다

잘못하면 메서드가 많아질 수 있지만, 직교성(orthogonality)를 높여 오히려 메서드 수를 줄여주는 효과가 있습니다

(직교성이 높다 → 공통점이 없는 기능들이 잘 분리되어 있다 or 기능을 원자적으로 쪼개 제공한다)

[직교 - 두 벡터의 내적이 0 → 두 벡터에는 서로 영향을 주는 성분이 전혀 없음을 나타냅니다]

 

ex) java.util.List 인터페이스에서 주어진 원소의 인덱스를 찾아야 하는데, 전체 리스트가 아니라 지정된 범위의 부분리스트에서 인덱스를 찾는다고 해봅시다

 

이 기능을 구현하기위해선 3개의 매개변수가 필요합니다 

1. '부분리스트의 시작'

2. '부분리스트의 끝'

3. '찾을 원소'

 

그런데 List는 3개의 매개변수를 받는 메서드가 존재하는 것이 아니라, 부분 리스트를 반환는 subList 메서드와 주어진 원소의 인덱스를 알려주는 indexOf 메서드를 별개로 제공합니다

subList 가 반환한 부분리스트 역시 완벽한 List이므로 두 메서드를 조합하면 원하는 목적을 이룰 수 있습니다

 

2. 매개변수 여러 개를 묶어주는 도우미 클래스를 만듭니다 

도우미 클래스는 일반적으로 정적 멤버 클래스로 만듭니다 

매개변수 몇 개를 독립된 하나의 개념으로 볼 수 있을 때 사용하면 좋습니다

// Before
// SUIT는 enum타입이라고 가정 (스페이드, 하트 ...)
public void shuffle(int rank, SUIT suit){
}
// After
// rank, suit를 하나로 묶는 Card 도우미 클래스를 만든다.
public void shuffle(Card card){
}
// 내부 클래스로 정의
private static class Card{
        int rank;
        SUIT suit;
}

 

3. 1,2 기법을 혼합한 것으로, 객체 생성에 사용한 빌더 패턴을 메서드 호출에 응용

매개변수가 많을 때, 특히 그중 일부는 생략해도 괜찮을 때 도움이 됩니다 

모든 매개변수를 하나의 추상화한 객체를 정의하고, 클라이언트에서 setter를 호출해 값을 설정합니다

클라이언트는 먼저 필요한 매개변수를 다 설정한 후, execute 메서드를 호출해 앞서 설정한 매개변수 유효성 검사 후, 객체를 넘겨 계산합니다

 

매개변수의 타입으로는 클래스보다는 인터페이스가 더 낫다

매개변수로 적합한 인터페이스가 있다면 (구현체가 아닌) 그 인터페이스를 직접 사용합시다

예) 매개변수로 HashMap 대신 Map을 사용하자

그러면 TreeMap, ConcurrentHashMap 등등 어떤 Map 구현체도 인수로 건넬 수 습니다 

 

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

메서드 이름상 boolean을 받아야 의미가 더 명확할 때는 예외입니다

열거 타입을 사용하면 코드를 읽고 쓰기가 더 쉬워집니다

public enum TemperatureScale { FAHRENHEIT, CELSIUS }

TemperatureScale.newInstance(true)
TemperatureScale.newInstance(FAHRENHEIT.CELSIUS)

 

이 글은 “이펙티브 자바 3판” 책 내용을 정리한 글입니다.

만약 저작권 관련 문제가 있다면 “shk3029@kakao.com”로 메일을 보내주시면, 바로 삭제하도록 하겠습니다.