프로그래밍 노트/Effective 시리즈

규칙1. 생성자 대신 정적 팩터리 메서드를 사용할 수 없는지 생각해 보라

깡냉쓰 2018. 11. 26. 20:11
728x90
반응형

생성자 대신 정적 팩터리 메서드를 사용할 수 없는지 생각해 보라


클래스를 통해 객체를 만드는 일반 적인 방법은 public으로 선언된 생성자(constructor)를 이용하는 것이나, 한가지 방법이 더 존재한다. 

클래스에 public으로 선언된 정적 팩터리 메서드(static factory method)를 추가하는 것이다.

 

아래의 예는 기본타입 boolean 값을 Boolean 객체에 대한 참조(reference)로 변환하는 것이다.

 
public static Boolean valueOf(boolea b){
    return b ? Boolean.TRUE : Boolean.False;
}

public으로 선언된 생성자 대신 정적 팩터리 메서드를 제공하는 방법의 장단점은 다음과 같다

 

장점

  1. 생성자와 달리 정적 팩터리 메서드에는 이름(name)이 있음
    • 이름만 잘 짓는다면 코드의 가독성(readability)가 높아짐
  2. 호출할 때마다 새로운 객체를 생성할 필요가 없다는 것
    • 불변 클래스라면 이미 만들어 둔 객체를 활용할 수도 있고, 만든 객체를 캐시(cache) 해놓고 재사용하여 같은 객체가 불필요하게 거듭 생성되는 일을 피할 수도 있음
    • Boolean.valueOf 나 Integer.valueOf 가 그 예인데, 많이 사용되는 객체 (ex. Integer(1)) 는 캐시해서 저장하고 있는 것으로 알고 있음 (Flyweight 경량패턴과 유사)
  3. 생성자와 달리 반환값 자료형의 하위 자료형 객체를 반환할 수 있다는 것
    • 객체의 클래스를 훨씬 유연하게 결정 가능 => 이해가 잘안되니 나중에 한번 봐야할 듯
  4. 형인자 자료형(parameterized type) 객체를 만들 때 편하다는 점
Map<String, List<String>> m = new HashMap<String, List<String>>();
 
public static <K, V> hashMap<K, V> newInstance(){
    return new HashMap<K, V>();
}
 
Map<String, List<String>> m = HashMap.newInstance();

로 형인자 자료형을 쉽게 만들 수 있다는 의미인데, 1.7 이상에서는 Map<String, List<String>> m = new HashMap<>(); 생성자를 호출할 때도 자료형 유추가 이루어질 수 있게 되었음

 

보통 정적 펙터리 메서드의 이름으로 다음과 같은 것들을 사용한다.

valueOf : 인자로 주어진 값과 같은 값을 갖는 객체를 반환한다는 뜻. 형변환 (type-conversion) 메서드

of : valueOf를 더 간단하게 쓴 것

getInstance

newInstacne : getInstace와 같지만 호출할 때마다 다른 객체를 반환한다.

 

단점

  1. public 이나 protected로 선언된 생성자가 없으므로 하위 클래스를 만들 수 없음
  2. 정적 팩터리 메서드가 다른 정적 메서드와 확연히 구분되지 않음

 

728x90
반응형