본문 바로가기
Java관련/Java

정적팩토리 메서드

by devstep 2022. 4. 9.

정적팩토리 메서드

특징

  • 추상 팩토리 패턴, 팩토리 메서드 패턴과 무관하다
  • 단순하게 인스턴스를 만들어서 리턴하는 팩토리 역할을 하는 메서드이다.

생성자대신 정적 팩터리 메서드 사용 고려

  1. 객체의 인스턴스 생성 시, 이름을 부여할 수 있다.
    • 생성자의 시그니처가 동일할 때 선언부를 동일하게 판단. 매개변수의 위치를 바꾸거나해서 우회적으로 생성자를 다르게 표현.
    • 하지만 생성자는 이름이 고정되어 있어 서로 다른 이유를 명칭하지 못한다.
    • 정적팩토리 메서드는 이름을 사용하여 객체의 인스턴스를 만들어주는 메서드를 만들 수 있다.
  2. 인스턴스를 통제할 수 있다.
    • 생성자를 private으로 하여 외부에서 객체를 생성할 수 없게 한다.
    • 정적팩토리 메서드를 통해 객체를 사용하게 한다.
    • 이렇게 하면 여러 개의 인스턴스를 만들 수 없다.
    • Boolean.valueOf()처럼 매개변수에 따라 각기 다른 인스턴스를 리턴해줄 수도 있다.
    • 플라이웨이트 패턴
      • 자주 사용하는 값들을 미리 캐싱해서 넣어놓고 꺼내놓고 쓰는 패턴.
      • 인스턴스를 통제하기 때문에 미리 자주 사용하는 객체를 만들어놓고 꺼내놓고 쓰는 플라이웨이트 패턴과 의미가 같다.
  3. 해당하는 클래스 인스턴스만 만들어주었는데, 정적팩토리 메서드는 리턴하는 반환타입에 호환가능한 다른 타입의 인스턴스를 리턴할 수 있다.
  4. 인터페이스 기반의 프레임워크를 사용할 수 있게 해준다.
    • 자바8부터는 interface에 static method를 선언할 수 있다.
    • 클라이언트에 구체타입을 숨길 수 있다.
public interface HelloService {

    public String hello();

    static HelloService of(String lang) { //HelloService인터페이스 구현체를 리턴해줄 수 있다.
        if(lang.equals("ko")) {
            return new KoreanHelloService();
        } else {
            return new EnglishHelloService();
        }
    }
}

public class HelloServiceFactory {
    public static void main(String[] args) {
        HelloService ko = HelloServiceFactory.of("ko");
    }
}
  1. 정적 팩토리 작성 시점에 구지 구현체가 없어도 된다.
    • 자바가 제공하는 정적팩토리 메서드 Loader
    • 파일 안에 구현체 작성
    • 파일명은 구현체 풀패키징이름(.으로 연결)을 적어준다.
public class HelloServiceFactory {
    public static void main(String[] args) {
        ServiceLoader<HelloService> loader = ServiceLoader.load(HelloService.class);
        Optional<HelloService> helloServiceOptional = loader.findFirst();
        helloServiceOptional.ifPresent(h -> {
            System.out.println(h.hello());
        });
    }
}

단점

  • 정적팩토리 메서드는 메서드 부분에 있기 때문에 한 눈에 객체 인스턴스를 얻을 방법을 보기 힘들다.
    • 원래는, javaDoc에 Constructor 부분이 따로 나와있어 용도를 분명히 알 수 있다.
  • Method Summary를 손쉽게 찾을 수 있도록 흔히 사용하는 네이밍 패턴을 제안하고 있다.
  • 가장 좋은 방법은 문서화를 하는 것이다. 문서화는 JavaDoc을 이용하여 한다.
    • of : 여러 매개변수를 받아서 인스턴스를 생성해서 반환 (또는 valueOf)
    • from : 하나의 매개 변수를 받아서 인스턴스를 생성해서 반환
    • get : 생성된 인스턴스 가져오는 경우 (또는 getInstance)
    • newInstance : 매번 팩토리 안에서 객체를 새로 만들 경우
  • 문서화 예시
/**
 * 이 클래스의 인스턴스는 #of()를 통해 사용한다.
 * @see #of() 
 */

'Java관련 > Java' 카테고리의 다른 글

Objects.requireNonNull() - java.util.Objects  (0) 2022.04.16
static  (0) 2022.04.13
로깅 라이브러리 Logging Library  (0) 2022.04.11
JAVA11 설치하기  (0) 2022.03.12
두 개의 리스트List값 비교 방법  (0) 2022.02.22

댓글