정적팩토리 메서드
특징
- 추상 팩토리 패턴, 팩토리 메서드 패턴과 무관하다
- 단순하게 인스턴스를 만들어서 리턴하는 팩토리 역할을 하는 메서드이다.
생성자대신 정적 팩터리 메서드 사용 고려
- 객체의 인스턴스 생성 시, 이름을 부여할 수 있다.
- 생성자의 시그니처가 동일할 때 선언부를 동일하게 판단. 매개변수의 위치를 바꾸거나해서 우회적으로 생성자를 다르게 표현.
- 하지만 생성자는 이름이 고정되어 있어 서로 다른 이유를 명칭하지 못한다.
- 정적팩토리 메서드는 이름을 사용하여 객체의 인스턴스를 만들어주는 메서드를 만들 수 있다.
- 인스턴스를 통제할 수 있다.
- 생성자를 private으로 하여 외부에서 객체를 생성할 수 없게 한다.
- 정적팩토리 메서드를 통해 객체를 사용하게 한다.
- 이렇게 하면 여러 개의 인스턴스를 만들 수 없다.
- Boolean.valueOf()처럼 매개변수에 따라 각기 다른 인스턴스를 리턴해줄 수도 있다.
- 플라이웨이트 패턴
- 자주 사용하는 값들을 미리 캐싱해서 넣어놓고 꺼내놓고 쓰는 패턴.
- 인스턴스를 통제하기 때문에 미리 자주 사용하는 객체를 만들어놓고 꺼내놓고 쓰는 플라이웨이트 패턴과 의미가 같다.
- 해당하는 클래스 인스턴스만 만들어주었는데, 정적팩토리 메서드는 리턴하는 반환타입에 호환가능한 다른 타입의 인스턴스를 리턴할 수 있다.
- 인터페이스 기반의 프레임워크를 사용할 수 있게 해준다.
- 자바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");
}
}
- 정적 팩토리 작성 시점에 구지 구현체가 없어도 된다.
- 자바가 제공하는 정적팩토리 메서드 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 |
댓글