•
클래스는 생성자와 별도로 정적 팩토리 메소드를 제공할 수 있다.
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
Java
복사
•
장점
◦
이름을 가질 수 있다.
▪
정적 팩토리는 이름만 잘 지으면 반환될 객체의 특성을 쉽게 묘사할 수 있다.
◦
호출될 때마다 인스턴스를 새로 생성하지 않아도 된다.
▪
이 덕분에 불변 클래스는 인스턴스를 미리 만들어 놓거나 새로 생성한 인스턴스를 캐싱하여 재활용하는 방식으로 불필요한 객체 생성을 방지할 수 있다.
•
ex) Boolean.valueOf(b)
▪
반복되는 요청에 같은 객체를 반환하게끔 하는 식으로 정적 팩토리 방식의 클래스는 언제 어느 인스턴스를 살아 있게 할지 통제할 수 있다.
▪
이를 인스턴스 통제 클래스라 하며 인스턴스를 통제하면 클래스를 싱글턴으로 유지할수도, 인스턴스화 불가로 만들 수도 있다.
▪
불변 값 클래스인 경우, 동등한 인스턴스가 단 하나뿐임을 보장할 수 있다.
◦
반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.
▪
이 능력은 반환할 객체의 클래스를 자유롭게 선택할 수 있게 하는 엄청난 유연성을 선물한다.
⇒ 이러면 해당 객체의 클래스도 정적 팩토리 메소드로..? 아니면 public 생성자를 사용해야 할텐데..
◦
입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
▪
반환 타입의 하위 타입이기만 하면 어떤 클래스의 객체를 반환하든 상관없다.
◦
정적 팩토리 메소드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
▪
인터페이스를 반환하므로 구현 시점을 뒤로 미룰 수 있다..!
•
단점
◦
상속을 하려면 public이나 protected 생성자가 필요하니 정적 팩토리 메소드만 제공하면 하위 클래스를 만들 수 없다.
▪
유틸리티 구현 클래스들은 상속할 수 없다는 얘기다.
◦
정적 팩토리 메소드는 프로그래머가 찾기 어렵다.
▪
생성자처럼 API 설명에 명확히 드러나지 않으니 사용자는 정적 팩토리 메소드 방식 클래스를 인스턴스화할 방법을 알아내야 한다.
▪
다음은 정적 팩토리 메소드에 흔히 사용하는 명명 방식들이다.
•
from : 매개변수 하나를 받아서 해당 타입의 인스턴스를 반환하는 형변환 메소드
◦
Date d = Date.from(instant);
•
of : 여러 매개변수를 받아 적합한 타입의 인스턴스를 반환하는 집계 메소드
◦
Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
•
valueOf : from과 of의 더 상세한 버전이다.
◦
BigInteger prime = BigInteger.valueOf(Integer.MAXS_VALUE);
•
instance, getInstance : 매개변수를 받는다면 매개변수로 명시한 인스턴스를 반환하지만 같은 인스턴스임을 보장하지 않는다.
◦
StackWalker luke = StackWalker.getInstance(options);
•
create, newInstance : instance, getInstance와 같지만 매번 새로운 인스턴스를 생성해 반환함을 보장한다.
◦
Object newArray = Array.newInstance(classObject, arrayLen);
•
get{Type} : getInstacne와 같으나 생성할 클래스가 아닌 다른 클래스에 팩토리 메소드를 정의할 때 쓴다.
◦
FileStore fs = Files.getFileStore(path);
•
new{Type} : newInstance와 같으나 생성할 클래스가 아닌 다른 클래스에 팩토리 메소드를 정의할 때 쓴다.
◦
BufferedReader br = Files.newBufferedReader(path);
•
{type} : getType과 newType의 간결한 버전이다.
◦
List<Complaint> litany = Collections.list(legacyLitany);