[Effective Java] 1. Static Factory Method

2 분 소요

객체를 생성하는 방법으로 생성자 외 정적 팩토리 메서드(Static Factory Method)를 사용하는 방법이 있다.

일반적인 생성자보다 장점이 많으니 무조건 생성자를 만들것이 아니라 static factory method를 만드는것을 고려해봐야 한다.

singleton 객체 생성에 자주 사용하는 방법으로 디자인패턴의 Factory Method 패턴과 무관하다.

1. Static Factory Method 의 장점

1.1. 객체 생성 메서드에 명시적인 이름을 부여한다.

만약 객체 생성의 Parameter에 따라서 생성되는 객체에 특징이 부여된다면.. 또는 경우에 따라서 다른 객체를 생성하여 리턴해야 한다면.. 이를 기존 생성자로 구별하기에는 어려움이 있다.

반면 static factory method를 사용하면 명시적으로 method 이름을 줄 수 있기 때문에 이를 구별할 수 있도록 구현 가능하다.

1.2. 호출할때마다 새로운 객체를 만들 필요가 없다.

생성자는 new 연산자를 통해 호출하기 때문에 반드시 새로운 객체가 생성된다.

반면 static factory method는 내부에서 객체 생성과정을 조율할 수 있기 때문에 새로운 객체생성이 강제되지 않는다.

Singleton 객체를 만들때도 주로 MyObject.getInstance() 와 같이 getInstance() 라는 static factory method를 주로 사용한다.

1.3. 리턴되는 클래스 타입을 유연하게 가져갈 수 있다.

생성자가 리턴하는 객체의 타입은 자기 자신이다.
반면 static factory method는 리턴할때 하위 객체타입을 리턴하도록 구현할 수 있다.

이러한 방법을 활용하면 public으로 선언되지 않은 class의 객체를 리턴하는 api를 만들수도 있다.

이 방법의 장점은 외부에 내부 구현체의 상세 내용을 숨길 수 있고 개념상의 무게감을 줄인다는 것이다.

이 기법은 인터페이스 기반 프레임워크 구현에 적합하다. 여기서 인터페이스가 static factory method의 리턴값으로 이용된다.
api를 사용하는 외부에서는 api의 인터페이스만 볼 수 있을 것이고, 실제 복잡하고 다양한 구현 내용은 api내부에 private으로 숨길 수 있다.

활용 예 1

Java의 Collection Framework에는 32개의 Collection interface 구현체가 있는데 반환되는 실제 class의 객체는 public이 아니다.

만약 모든 class가 public 생성자를 가지고 있는 경우라면 외부에서 사용하는 입장에서 api가 훨씬 복잡하고 사용이 어렵게 느껴졌을 것이다.

활용 예 2

JDK 1.5부터 도입된 java.util.EnumSet은 public 생성자가 없이 static factory method 뿐이다. 이 메서드들은 객체를 생성할때 파라미터로 받는 enum 개수에 따라 다른 class 객체를 만들어 리턴한다.

이 api를 사용하는 곳에서는 내부에서 어떤 class를 사용하는지 관심이 없을 것이다.
반면 api를 만드는 입장에서는 추후 다음 버전에서 어떠한 기능적인 추가나 구현체 class를 더 추가하고자 할 때 외부의 영향을 받지 않도록 수정할 수 있다.

2. Static Factory Method 의 단점

2.1. 생성자가 없는 경우 상속을 사용할 수 없다.

static factory method만 제공하고 생성자를 private으로 막는 경우 상속관계를 가질 수가 없다.

자식 class의 생성자는 부모 class의 생성자를 호출해줘야 하는데 private으로 막히기 때문이다.

자바의 Collection 프레임워크에 포함된 모든 구현 class들은 public 생성자를 가지지 않는데 이 때문에 이를 상속한 자식 class를 만들 수 없다.
이는 논쟁의 여지가 있는데 계승(inheritance)보다 구성(composition)을 쓰도록 장려한다는 점에서 긍정적으로 평가하는 사람들도 있다.

2.2. 다른 method와 확실히 구분되지 않는다.

api 문서에서 생성자는 확실히 구분이 되지만 static factory method는 다른 일반 method와 구분이 되지 않는다.

따라서 이를 보는 사람에게는 다소 혼란이 있을 수 있다.
일반 method와 구분하기 위해 static factory method는 이름이 중요한데 일반적으로 자주 사용하는 것들은 아래와 같다.

이름 설명
valueOf parameter로 받은 값과 같은 값을 갖는 객체를 리턴한다.
of valueOf를 간단하게 쓴 것이다.
getInstance 객체를 리턴한다. 싱글턴에서는 parameter 없이 항상 같은 객체를 리턴한다.
newInstance getInstance와 같지만 항상 새로운 객체를 리턴한다.
getType getInstance와 같지만 factory method가 다른 class에 있을때 사용한다. “Type”은 리턴할 Class 이다.
newType newInstance와 같지만 factory method가 다른 class에 있을때 사용한다. “Type”은 리턴할 Class 이다.

댓글남기기