티스토리 뷰

개발/Java

Static factory method

haloper 2016. 5. 1. 12:39

Static factory method의 장단점


Static factory method란 객체의 인스턴스를 생성하는 방법 중에 하나입니다. public 생성자를 private으로 가려 놓고, 생성자로 사용하고자 하는 static method를 public으로 선언하여 해당 method만 이용해서 인스턴스를 생성하도록 하는 방식 입니다.

이런 방식을 사용함으로 인해 얻을 수 있는 이점이 몇 가지 있습니다.


1. 객체 생성에 대한 별도의 의미를 부여해 줄 수 있습니다. 생성자는 class 이름과 동일하기 때문에 특별한 의미를 부여하기 힘듭니다. 클래스의 생성자 시그너처를 여러개 만들어 각 시그너처 별로 기능을 다르게 하고 주석으로 의미를 설명해 줄 순 있지만, 클래스를 사용하는 입장에서 시그너처로 기능이 구분되는 것은 가독성을 떨어뜨릴 수 있습니다. 또한 하나의 시그너처에 여러개의 기능을 부여할 수 없는 단점도 존재합니다. 반면, Static factory method를 사용할 경우 생성자의 기능별로 이름을 다르게 설정하여 그런 문제점들을 보완해 줄 수 있습니다.


2. 인스턴스 생성을 조절할 수 있습니다. Static factory method 사용 시 생성되는 객체의 수를 조절할 수 있으며, 이미 만들어 놓은 인스턴스를 재활용 할 수도 있습니다. 객체 생성에 드는 비용이 크거나, 많은 수의 객체 생성이 필요한 경우 이런한 장점은 성능상의 큰 이점을 줍니다.


3. 반환 인스턴스를 하위 클래스로 만들어 반환할 수 있습니다. 클라이언트가 인터페이스를 이용하고 인터페이스를 구현한 어떤 클래스를 인스턴스화 하여 사용할 경우, static factory method는 인스턴스의 내부 구현은 숨긴 채로, 상황에 따라 적절한 클래스의 인스턴스를 반환해 줄 수 있습니다. 이는 추후 내부 구조가 변경되어 구현체를 바꿔야 되는 상황에서도 클라이언트의 코드는 전혀 건드릴 필요가 없게 됩니다.


Static factory method에는 몇가지 단점도 존재합니다. 우선, public이나 protected로 정의된 생성자가 없으므로 하위 클래스를 만들 수 없습니다. 하위 클래스 생성 시에 상위 클래스의 생성자도 무조건 호출되어야 하지만, 접근제어로 인해 호출 불가능 하기 때문입니다. 또한, static factory method는 일반 static method와 별도로 구분되지 않는다는 단점도 있습니다.



Iteger class에 대하여...


Static factory method를 사용하고 있는 Integer class에 대하여 살펴 보도록 하겠습니다.


* Main.java

public class Main {
	
	public static void main(String[] args) {
		Integer a = new Integer(1); //생성자를 이용해서 객체 생성
		Integer a2 = new Integer(1);
		Integer b = Integer.valueOf(1); //static factory method를 이용해서 객체 생성
		Integer c = Integer.valueOf(1); //b와 동일한 객체를 반환함
		
		System.out.println(a == a2); //false;
		System.out.println(a == b); //false
		System.out.println(b == c); //true
		
		int d = 1;
		System.out.println(a == d && b == d);  //true?
		Integer e = Integer.valueOf(9999);
		Integer f = Integer.valueOf(9999);
		System.out.println(e == f); // false
	}

}


a 와 a2 는 new 키워드를 이용하여 public 생성자를 통해 객체를 생성하였고, b 와 c 는 static factory method를 이용해서 객체를 생성했습니다. == 구문을 이용하여 두 객체를 비교할 경우 두 객체가 동일한 메모리 주소에 존재하는 경우에만 true를 리턴합니다. new 키워드를 이용해서 객체를 생성한 경우 힙 메모리에 1의 값을 가진 또 하나의 객체가 만들어지게 되어, 같은 값을 가진 객체라도 == 비교 시 false 값을 가지게 됩니다. 그래서 a 와 a2는 같은 값을 가졌지만, a == a2 는 false 값을 가지게 됩니다.

반면, static factory method를 이용해서 객체를 생성한 경우, Integer class에서 관리하는 값(보통 -128 ~ 127, max값은 변경 가능)의 경우 기존에 만들어 두었던 객체를 재활용 하기 때문에 == 비교시에도 true 값을 가질 수 있습니다.


* Integer.class의 valueOf

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high) // cache 내에 존재하는 값이면 cache 객체 사용
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i); //아니면 new로 생성
}


- a == d && b == d 가 true인 이유는 Integer type 과 int type 비교 시에 Integer type을 자동으로 unboxing 해주기 때문입니다.


- e == f 가 false 인 이유는 9999 란 값이 cache 영역에 포함되지 않기 때문에 관리되어 지지 않고, valueOf 호출 시마다 별도의 인스턴스를 따로 생성하기 때문입니다.



'개발 > Java' 카테고리의 다른 글

Java String #1  (0) 2016.05.30
Builder Pattern  (0) 2016.05.06
Spring Value Annotation 사용시 참고 사항  (0) 2016.04.17
디자인 패턴 - Decorator, Adapter, Facade 패턴  (0) 2016.04.04
디자인 패턴 - Command Pattern  (0) 2016.03.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함