Java

정적 팩토리 메소드

욕심만 많은 사람 2023. 7. 16. 01:57

정적 팩토리 메소드 (static factory method)란?

정적 팩토리 메소드를 사용하면 객체를 생성하기 위해 직접 new 키워드를 사용하여 생성자를 호출하지 않습니다.

기존의 public 생성자는 접근 지정자를 private으로 바꾸어 외부에 감추고, static method를 사용해서 간접적으로 생성자를 호출해 객체를 생성하는 것이 정적 팩토리 메소드 입니다.

아래 코드는 Boolean class에서 사용한 정적 팩토리 메소드 입니다.

public static Boolean valueOf(boolean b){
	return b ? Boolean.TRUE : Boolean.FALSE;
}


왜 사용할까?

‘이펙티브 자바’에서 가장 첫 번째 챕터는 다음과 같다.

생성자 대신 정적 팩토리 메서드를 고려하라

1. 의미있는 이름 부여

생성자 자체로는 매개변수와 반환될 객체의 특성을 제대로 설명할 수 없습니다. 반면 정적 팩토리 메소드는 반환될 객체의 특성을 설명하는 의미있는 이름을 부여할 수 있습니다.

특히 각각 다른 매개변수를 갖는 여러 개의 생성자가 있다면 더더욱 정적 팩토리 메소드 사용을 추천합니다.

가령 Command라는 명령어 객체가 있다고 합시다.

public Command(String input) {
    validateInput(input);
    this.input = input;
}

// Command 객체를 생성한다.
Command command = new Command("A5");

생성자를 직접 호출해서 객체를 생성하는 것보다 아래처럼 정적 팩토리 메소드를 사용하면 이해하기 쉽습니다.

private Command(String input) {
    validateInput(input);
    this.input = input;
}

public static Command from(String input) {
    return new Command(input);
}

// Command 객체를 생성한다.
Command command = Command.from("A5");

2. 호출될 때마다 인스턴스 생성X

인스턴스를 캐싱하여 재활용하는 방식으로 불필요한 객체 생성을 피할 수 있습니다.

3. 반환 타입의 하위 타입 객체를 반환 가능

반환할 객체의 클래스를 자유롭게 선택할 수 있습니다.

이를 응용하면 입력받는 매개변수에 따라 다른 클래스의 객체를 반환할 수 있습니다.


단점

1. 하위 클래스 생성 불가능

상속을 하려면 public 혹은 protected 생성자가 필요합니다.

하지만 정적 팩토리 메소드를 사용하는 경우 접근 지정자를 private으로 해야하기 때문에 정적 팩토리 메소드만을 제공하면 하위 클래스를 만들 수 없습니다.

2. 개발자가 찾기 힘듦

생성자 처럼 정해진 키워드를 사용하는 것이 아니기 때문에 명확히 드러나지 않습니다.


네이밍 규칙

  • from : 하나의 매개 변수를 받아서 객체를 생성한다.
public static Command from(String input) {
    return new Command(input);
}

  • of : 여러 개의 매개 변수를 받아서 객체를 생성한다.
Set<Rank> cards = EnumSet.of(JACK, QUEENS, KING);

  • valueOf : fromof 보다 더 자세하게 설명한다.
public static Boolean valueOf(boolean b){
	return b ? Boolean.TRUE : Boolean.FALSE;
}

  • instance | getInstance : 인스턴스 생성, 같은 인스턴스임을 보장하지 않는다.

  • create | newInstance : 매번 새로운 인스턴스를 생성한다.

  • get[Type] : getInstance와 같지만, 생성할 클래스가 아닌 다른 클래스에 팩토리 메소드를 정의할 때 사용한다.
FileStore fs = Files.getFileStore(path);


Reference.

[도서] 이펙티브 자바