Open-Closed Principle

[객체의 생성과 소멸] 생성자 대신 Static 팩토리(factory) 메소트 사용을 고려하자 본문

Programming/Java

[객체의 생성과 소멸] 생성자 대신 Static 팩토리(factory) 메소트 사용을 고려하자

대박플머 2014. 6. 24. 00:26

이 포스팅의 내용은 Effective Java의 내용을 요약 정리하면서 올리는 것이다. 

참고 하기 바란다. 

--------------------------------------------------------------------------------------------------------------

클래스를 사용하기 위해서는 생성자를 호출하여 인스턴스를 초기화해야 한다. 

그래서 우리는 생성자를 통해 클래스 인스턴스를 사용할 수 있는 최적의 상태로 만든다. 

그런데 이 책에서는 public static을 사용하라고 권장한다. 

이유

첫째, 생성자와 달리 자기 나름의 이름을 가질 수 있다는 것이다. 

자바 클래스는 동일한 시그니처를 갖는 생성자를 한나만 가질 수 있다. 이런 제약을 해결하기 위해 프로그래머들은 타입이 다른 매개변수의 순서만을 바꾸어 두 개의 생성자로 만든다. 그러나 이 방법은 좋지 않다. 그 클래스의 사용자는 자신이 필요한 생성자가 어떤 것인지 기억하기도 어려울뿐더러, 실수로 다른 생성자를 호출 할 수도 있기 때문이다. 또한 그런 생성자를 사용하는 코드를 파악하려는 사람들은 생성자가 정의된 클래스의 문서를 봐야만 그 코드를 이해할 수 있을 것이다. 

static 팩토리 메소드는 자신의 이름을 가질 수 있으므로, 앞의 생성자와 같은 제약을 갖지 않는다. 따라서 하나의 클래스에 동일한 시그니처를 갖는 여러 개의 생성자가 필요한 경우에는 생성자대신 static 팩토리 메소드를 사용하되, 메소드 간의 차이점을 부각시키도록 신중하게 이름을 선정한다. 


둘째, 생성자와 달리 호출될 때마다 매번 새로운 객체를 생성할 필요가 없다는 것이다. 

불필요하게 중복된 인스턴스들이 생성되는 것을 방지하기 위해 이미 생성된 인스턴스들을 저장했다가 반복 사용할 수 있다. 이 기법은 Flyweight 패턴과 유사하며, 동일한 객체가 자주 사용될 때, 특히 객체 생성시 자원이나 시간이 많이 든다면 프로그램 성능을 크게 향상시킬 수 있다. 


셋째, 자신의 클래스 인스턴스만 반화하는 생성자와 달리, static 팩토리 메소드는 자신이 반화는 타입의 어떤 서브타입(Subtype) 객체도 반환할 수 있다는 것이 세번째 장점이다. 반환되는 객체의 클래스를 선택해야 할 때 뛰어난 유연성을 제공한다. 

네번째, 매개변수화 타입의 인스턴스를 생성하는 코드를 간결하게 해준다는 것이다. 

1
2
3
4
5
6
7
8
9
10
11
 
// 1
Map<String, List<String>> m = new HashMap<String, List<String>>();
 
//2
public static <K, V> HashMap<K, V> newInstance(){
         return new HashMap<K, V>();
}
 
Map<String, List<String>> m = HashMap.newInstance();
 



단점, 

첫번째, 인스턴스 생성을 위해 static 팩토리 메소드만 갖고 있으면서 public이나 protected 생성자가 없는 클래스의 셩우는 서브 클래스를 가질 수 없다는 것이다. public static 팩토리 메소드에서 반환하는 객체의 클래스가 public이 아닌 경우도 마찬가지이다. 

두번째, 다른 static 메소드와 쉽게 구별할 수 없다는 것이다. API 문서에서 생성자는 별도로 표시되어 금방 알아볼 수 있지만, static 팩토리 메소드는 다른 메소드와 섞여있어 잘 구분되지 않는다. 


요약

static 팩토리 메소드와 public 생성자는 모두 나름의 용도가 있으므로 상호간의 장점을 아는 것이 중요하다. 대개의 경우 static 팩토리 메소드가 더 좋을 떄가 많다. 그러므로 static 팩토리 메소드를 먼저 고려하지 않고 무심코 public 생성자를 사용하는 습관을 피하자.