자바 프로그래밍 언어에서 메서드 시그니처는 다음과 같다.
- 메서드 명 ⭕️
- 파라미터의 순서, 타입, 개수 ⭕️
- 리턴 타입 ❌
- Exceptions ❌
// 모두 서로 다른 메서드 시그니처
public void method() { }
public void method2() { }
public void method(int a) { }
public void method(String s) { }
public void method(int a, int b) { }
// 서로 같은 메서드 시그니처
public void method() { }
public int method() { }
public String method() throws Exception { }
같은 패키지에 속한 다른 이름들과 일관되게 짓는 게 최우선 목표이다. 그 다음은 개발자 커뮤니티에서 널리 받아들여지는 이름을 사용하는 것이다.
- 메서드 이름은 lowerCamelCase로 작성한다.
- 메서드 이름은 동사/전치사로 시작한다.
- 예약어를 사용해서는 안 된다. (ex. do, while..)
- get/set()
public LottoNumber getLottoNumber() { }
- init(데이터 초기화)
public void initStatistics() { }
- is/has/can(boolean 값 리턴)
// is - 맞는지 틀리는지 여부
public boolean isPositive() { }
// has - 데이터 소지 여부
public boolean hasWinningNumber() { }
// can - 할 수 있는지 여부
public boolean canOrderLotto() { }
- create(새로운 객체 생성 후 리턴)
public LottoTicket createLottoTicket() { }
- find(데이터 찾기)
public LottoTicket findFirstLottoTicket() { }
- to(다른 형태의 객체로 반환)
public LottoNumber toLottoNumber(int number) { }
- by
public Rank getRankBy(WinningLotto winningLotto) {}
- 왜 존재해야 하는가
- 무슨 작업을 하는가
- 어떻게 사용하는가
public List<Rank> getRanksBy(WinningLotto winningLotto) {
// 왜 존재해야 하는가 - WinningLotto를 이용해서 로또의 등수를 얻기 위해
// 무슨 작업을 하는가 - WinningLotto와 비교하여 알맞은 등수를 가져온다.
// 어떻게 사용하는가 - WinningLotto를 매개변수로 받아서 여러개의 로또들의 등수를 계산한다.
}
convenience method 말 그대로 편의를 위해서 존재하는 메서드 입니다.
편의 메서드는 없어도 기능적으로 문제가 없지만 자주 사용하는 메서드를 여러개 묶어서 새로운 메서드를 만들던가, 메서드에 이름을 부여하여 좀 더 명확하게 무슨 일을 하는지 표현해줍니다.
// 자주 사용하는 메서드를 여러개 묶어서 새로운 메서드를 만듦
private void validateNumber() {
validateEmpty();
validateNegaive();
validateRange();
validateDuplication();
}
// 메서드에 이름을 부여하여 좀 더 명확하게 무슨 일을 하는지 표현
private static boolean isSecondRank(int matchCount, boolean matchBonusNumber) {
return matchCount == Rank.SECOND.matchCount && matchBonusNumber;
}
메서드가 너무 많은 클래스는 문서화하고, 테스트하고 유지보수하고 사용하기 어렵습니다
책에서 추천하는 내용은 4개 이하가 좋다고 하며, 특히 같은 타입의 매개변수 여러 개가 연달아 나오는 경우가 특히 해롭다고 합니다. 만약 메서드에 매개변수가 너무 많을 때 줄이는 방법을 아래와 같이 소개합니다.
//Bad Case
public Rank getRankBy(LottoNumber number1, LottoNumber number2, LottoNumber number3,
LottoNumber number4, LottoNumber number5, LottoNumber number6, LottoNumber bonus) {}
여러 메서드를 쪼개어 원래 많았던 매개변수 목록을 메서드들이 나누어 갖도록 한다. 잘못하면 메서드의 숫자가 많아질 수 있지만 오히려 직교성을 높여서 오히려 메서드 수를 줄여주는 효과가 있다.
직교성: "공통점이 없는 기능들이 잘 분리되어 있다." "기능을 원자적으로 쪼개 제공한다."
//Bad Case
public double matchLottoAndCalculateYield(LottoTickets lottoTickets, WinningLotto winningLotto, Money inputMoney, ....) {}
//Good Case
public List<Rank> getRanksBy(LottoTickets lottoTickets, WinningLotto winningLotto) {}
public Money calculateTotalReward(List<Rank> ranks) {}
public double calculateYield(Money inputMoney, Money reward) {}
도우미 클래스란?
하나의 개념으로 묶일 수 있는 정적 멤버 클래스를 두고 있는 클래스
//Bad Case
public void giveCard(String suit, int number, int height, int width) {}
//Good Case
class Blackjack {
// 도우미 클래스 (정적 멤버 클래스)
static class Card {
private String suit;
private int number;
private int height;
private int width;
}
public void giveCard(Card card);
}
인터페이스 대신 구현체 클래스를 매개변수로 타입으로 설정한다면 메서드를 사용하는 클라이언트에게 특정 구현체만 사용하도록 제한하는 꼴이기에 인터페이스를 사용하자
//Bad Case
public Statistics createStatistics(HashMap<Rank, Integer> result) {}
createStatistics(new HashMap<>());
//Good Case
public Statistics createStatistics(Map<Rank, Integer> result) {}
createStatistics(new HashMap<>());
createStatistics(new LinkedHashMap<>());
createStatistics(new TreeMap<>());
열거 타입을 사용하면 코드를 읽고 쓰기가 더 쉬워지며, 나중에 선택지를 추가하기도 쉽다.
//Bad Case
public LottoTicket publishLotto(boolean isAuto) {}
//Good Case
public enum LottoType{
Auto,
Manual;
}
public LottoTicket publishLotto(LottoType lottoType) {}
- 이펙티브 자바 아이템 51
- 좋은 코드를 위한 자바 메서드 네이밍