[Effective Java] 아이템 51 - 메서드 시그니처를 신중히 설계하라
메서드 이름을 신중히 짓자.
항상 표준 명명 규칙을 따르며 같은 패키지에 속한 다른 이름들과 일관되게 짓는게 최 우선이다.
다음 목표는 개발자 커뮤니티에서 널리 쓰이는 이름을 사용하고 너무 긴 이름은 피하자
편의 메서드를 너무 많이 만들지 말자.
모든 메서드는 각자 자신의 소임을 다해야 한다. 메서드가 너무 많은 클래스나 인터페이스는 익히고, 사용하고, 유지보수하기 어렵다.
클래스나 인터페이스는 자신의 각 기능을 완벽히 수행하는 메서드로 제공해야 한다. 확신이 서지 않으면 만들지 말자.
매개변수 목록은 짧게 유지하자.
매개 변수목록이 너무 많다면 전부 기억하기 어렵고 API문서를 옆에 끼고 개발해야 한다.
특히나 같은 타입의 매개변수가 여러개 나오는 경우가 가장 해롭다. 순서를 기억하기 어렵고 헷갈려서 순서를 뒤집어 입력하게 되면 오류없이 그대로 컴파일되고 실행되어 기대한 결과를 얻기 힘들다. 매개변수 목록을 짧게 하기 위해 다음을 참고해 보자
- 여러 메서드로 쪼갠다.
쪼개진 메서드는 각각 원래 매개변수 목록의 부분집합을 받는다.
잘못하면 메서드가 너무 많아질 수 있지만 직교성을 높여 오히려 메서드가 줄어들 수 있다. List가 좋은 예이다.
주어진 범위의 부분 리스트에서 원소를 찾는 메서드는 '부분 리스트의 시작', '그 끝', '찾을 원소' 까지 총 3개의 매개변숙가 필요하다. 하지만 List는 이렇게 하지 않고 부분 리스트를 반환하는 메서드와 원소를 찾는 메서드만 지원하여 각 매개변수는 2, 1개가 된다.
결과적으로 강함과 유연함이 절묘하게 균형을 이루는 API가 만들어 진다.
직교성 이란?
소프트웨어에서 말하는 직교성은 공통점 없이 기능들이 잘 분리되어 있다. 긴으을 원자적으로 쪼개 제공한다는 뜻이다.
하나의 기능만 하는 함수를 제공하면 중복 없이 낮은 결합도를 유지하며 유연하게 코드를 짤 수 있다.
- 매개 변수 여러 개를 묶어주는 도우미 클래스를 만든다.
일반적으로 이런 도우ㅂ미 클래스는 정적 멤버 클래스로 둔다. 매개변수 몇 개를 하나의 개념으로 볼 때 유용한다.
카드의 숫자와 무늬를 뜻하는 두 매개변수를 항상 같은 순서로 전달할 때 이 둘을 묶는 도우미 클래스를 만들어 하나의 매개변수로 주고받으면 API는 물론 클래스 내부 구현도 깔끔해 진다. - 위의 두 기법을 합쳐보자.
객체 생성에 사용한 빌더 패턴을 메서드 호출에 응용할 수 있다. 이 기법은 매개변수가 많고 그 중 일부를 생략해도 괜찮을 때 유용하다. 모든 매개 변수를 하나로 추상화한 객체를 정의하고, 클라이언트에서 이 객체의 세터 메서들을 호출해 필요한 값을 설정하게 한다. 이때 각 세터 메서드는 연관된 몇개의 매개변수만 설정하게 한다. 클라이언트가 필요한 매개변수를 다 설정 했으면 excute()메서드를 호출해 앞에 설정한 매개변수들의 유효성을 검서한 후 설정 완료된 객체를 넘겨 원하는 계산을 한다.
매개변수의 타입으로는 클래스보다는 인터페이스가 낫다.
매개 변수로 인터페이스를 받으면 해당 인터페이스를 구현한 어떤 인터페이스 구현체도 인수로 건넬 수있다.
클래스로만 받으면 특정 구현체만 받도록 제한하는 꼴이며, 다른 구현체가 들어오면 객체로 옮겨 담느라 복사 비용만 들게 된다.
boolean 보다는 우너소 2개짜리 열거 타입이 낫다.
열거 타입을 사용하면 코드를 읽고 쓰기 쉬워진다.
예를 들어, 온도계 클래스의 정적 팩터리 메서드가 넘겨 받는 값에 따라 적합한 온도계 인스턴스를 생성해 준다고 해보자.
Thermometer.newInstance(true) 보단 Thermometer.newInstance(TemperatureScale.CELSIUS)가 훨씬 명확하다. 또한 나중에 켈빈 온도를 지원하도록 확장하기도 편하다.
단, 메서드 이름상 boolean을 받아야 의미가 더 명확할 때는 예외이다.