정적 팩토리 메서드란 객체 생성의 역할을 하는 클래스 메서드와 같은 의미로 요약할 수 있다.
아래의 코드를 보자. 다음 코드는 java.time패키지에 포함된 LocalTime클래스의 정적 팩토리 메서드이다.
// LocalTime.class
...
public static LocalTime of(int hour, int minute) {
ChronoField.HOUR_OF_DAY.checkValidValue((long)hour);
if (minute == 0) {
return HOURS[hour];
} else {
ChronoField.MINUTE_OF_HOUR.checkValidValue((long)minute);
return new LocalTime(hour, minute, 0, 0);
}
}
...
// hour, minutes을 인자로 받아서 9시 30분을 의미하는 LocalTime 객체를 반환한다.
LocalTime openTime = LocalTime.of(9, 30);
위 코드는 of메소드를 통해 집적접으로 생성자를 통해 객체를 반환하는 것이 아닌, 자체 메서드를 통해 객체를 생성하고 반환한다.
이처럼 생성자 외에, 개발자가 직접 명시하여 객체를 생성 및 리턴하는 메소드를 정적 팩토리 메서드라고 한다.
클래스를 정의할 때 public생성자 대신 정적 팩터리 메서드를 제공하면 다음과 같은 이점이 있다.
이름을 가질 수 있다.
소수인 BigInteger를 반환한다
’를 잘 표현할까?public class LottoFactory() {
private static final int LOTTO_SIZE = 6;
private static List<LottoNumber> allLottoNumbers = ...; // 1~45까지의 로또 넘버
public static Lotto createAutoLotto() {
Collections.shuffle(allLottoNumbers);
return new Lotto(allLottoNumbers.stream()
.limit(LOTTO_SIZE)
.collect(Collectors.toList()));
}
public static Lotto createManualLotto(List<LottoNumber> lottoNumbers) {
return new Lotto(lottoNumbers);
}
...
}
호출될 때마다 인스턴스를 새로 생성하지 않아도 된다.
public class LottoNumber {
private static final int MIN_LOTTO_NUMBER = 1;
private static final int MAX_LOTTO_NUMBER = 45;
private static Map<Integer, LottoNumber> lottoNumberCache = new HashMap<>();
static {
IntStream.range(MIN_LOTTO_NUMBER, MAX_LOTTO_NUMBER)
.forEach(i -> lottoNumberCache.put(i, new LottoNumber(i)));
}
private int number;
private LottoNumber(int number) {
this.number = number;
}
public LottoNumber of(int number) { // LottoNumber를 반환하는 정적 팩토리 메서드
return lottoNumberCache.get(number);
}
...
}
반환 타입의 하위 타입 객체를 반환할 수 있다.
public class Level {
...
public static Level of(int score) {
if (score < 50) {
return new Basic();
} else if (score < 80) {
return new Intermediate();
} else {
return new Advanced();
}
}
...
}
입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다
서브스를 제공하는 프레임워크는 다음과 같은 핵심 컴포넌트로 이루어진다.