클래스를 통해 객체를 만드는 방법은 세 가지가 있다.

  1. public으로 선언된 생성자
  2. 정적 팩터리 메서드
  3. 빌더 패턴

 

위의 세 가지 방법 중 가장 일반적인 것은 첫 번째 방법인데, 이 대신에 정적 팩터리 메서드를 사용할 수는 없는지 고려해보자.

정적 팩터리 메서드를 이용해 객체를 만드는 하나의 예시는 아래와 같다.

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

 

1. 생성자 대신 정적 팩터리 메서드를 사용할 때의 장점


첫 번째, 생성자와는 달리 정적 팩터리 메서드에는 이름이 있다.

예를 들어, 소수일 가능성이 높은 BigInteger 객체를 생성하는 생성자 BigInteger(int, int, Random) 대신 BigInteger.probablePrime처럼 표현하면 반환받을 객체에 대한 정보를 이름으로부터 대략 파악할 수 있게 된다.

 

두 번째, 생성자와는 달리 호출할 때마다 새로운 객체를 생성할지 또는 같은 객체를 반환할지(싱글톤) 선택할 수 있다.

위에서 예를 든 valueOf 메서드처럼 객체가 매번 생성되는 일을 피할 수 있다. 같은 객체를 반복해서 반환하게 되면 어떤 시점에 어떤 객체가 얼마나 존재할지를 정밀하게 제어할 수 있게 된다.

 

세 번째, 생성자와는 달리 반환 타입을 가지므로 상속 또는 구현체를 반환하도록 하는 전략을 구성할 수 있다.

정말 강력한 장점이라고 생각하는데 예를 들어, 특정 인터페이스를 반환 타입으로 가진다면 그 어떤 구현체를 반환할지를 내부 로직에서 선택할 수 있다. 여기서 주의할 점은, 인터페이스 자체는 정적 메서드를 가질 수 없기 때문에 관습상 반환 타입이 Type이라는 이름의 인터페이스인 정적 팩터리 메서드는 Types라는 이름의 객체 생성 불가능 클래스 안에 둔다.

 

예를 들어, Java의 컬렉션 프레임워크에는 32개의 컬렉션 인터페이스 구현체가 들어 있는데, 이 구현체들 거의 전부는 java.util.Collections라는 객체 생성 불가능 클래스의 정적 팩터리 메서드를 통해 이용한다.

 

2. 정적 팩터리 메서드명으로 사용되는 것들


일반적으로 다음과 같은 이름을 정적 팩터리 메서드명으로 사용한다.

  1. valueOf : 인자로 주어진 값과 같은 값을 갖는 객체를 반환한다는 뜻으로 이런 정적 팩터리 메서드를 형변환 메서드라 한다.
  2. of : valueOf를 더 간단하게 쓴 것.
  3. getInstance : 인자에 기술된 객체를 반환하지만, 인자와 같은 값을 갖지 않을 수도 있다. 싱글턴 패턴을 따를 경우 이 메서드는 인자 없이 항상 같은 객체를 반환한다.
  4. newInstance : getInstance와 같지만 호출할 때마다 다른 객체를 반환한다.
  5. getType : getInstance와 같지만, 반환될 객체의 클래스와 다른 클래스에 팩터리 메서드가 있을 경우에 사용한다. 예를 들어, Type은 팩터리 메서드가 반환할 객체의 타입이다.
  6. newType : newInstance와 같지만, 반환될 객체의 클래스와 다른 클래스에 팩터리 메서드가 있을 경우에 사용한다. 예를 들어, Type은 팩터리 메서드가 반환할 객체의 타입이다.