팩토리란 ?
팩토리(Factory) 는 '공장' 이라는 뜻을 가지고 있다.
일반적으로 클래스의 객체를 생성할 때, 생성자
를 통해서 객체를 생성하지만 팩토리 메서드
라는 공장을 통해서 객체를 만들 수도 있다.
그럼, 팩토리 메서드를 사용한 것과 생성자를 사용한 것이 무슨 차이가 있는 것 인가요?
굳이 팩토리 메서드를 만들어서 인스턴스를 생성하는 번거로운 작업을 왜 해?
이것에 대한 답변을 들어보기 전에, 여러분들도 한 번 고민해 보자
팩토리 메서드
public class Person{
private int age;
Person(int age){
this.age = age;
}
}
이것은 우리가 자바 기본서에서 지겹도록 봐왔던 클래스 구조다.
Person p = new Person(10);
그리고 우리는 객체를 생성할 때, 위와 같이 생성자 호출을 통해서 객체를 생성해왔다.
그런데 우리는 생성자의 인자만 봐서는 이것이 나이를 나타내는 것인지, 10 원짜리 동전을 가지고 있다는 것인지 클래스를 뜯어보지 않고서는 도무지 알 길이 없다.
하지만 이것을 팩토리 메서드로 구현한다면 어떨까
public class Person{
private int age;
private Person(int age){
this.age = age;
}
public static Person ofAge(int age){
return new Person(age);
}
}
Person p = Person.ofAge(10);
위 코드를 보고 여러분은 인자 값이 '나이' 라는 것을 쉽게 추측할 수 있다.
또한 생성자를 private 으로 변경해서 팩토리 메서드를 통한 객체 생성을 강제하고 있다.
이것이 팩토리 메서드의 장점이다.
팩토리 메서드의 장점
첫 번째 장점은, 생성자와는 달리 팩토리 메서드에는 이름이 있다는 것이다. 생성자는 이것이 어떤 객체가 생성되는지 쉽게 알 수 없지만, 팩토리 메서드는 이름을 잘 지어 놓으면 코드의 가독성이 높아지며 사용하기도 쉬워진다.
두 번째 장점은, 생성자와 달리 호출할 때마다 새로운 객체를 생성할 필요가 없다. 때문에, 동일한 객체가 요청되는 일이 잦고, 객체를 만드는 비용이 클 때 적용시키면 성능을 크게 개선할 수 있다.
세 번째 장점은, 생성자와 달리 반환값 자료형의 하위 자료형 객체를 반환할 수 있다. 따라서 반환되는 객체의 클래스를 훨씬 유연하게 결정할 수 있다. 이 유연성을 활용하면 public으로 선언되지 않은 클래스의 객체를 반환할 수 있기 때문에 구현의 세부사항을 감출 수 있어 간결한 코드가 된다. 예로는 인터페이스 기반 프레임워크 구현이 있다.
네 번째 장점은, 형인자 자료형 객체를 만들 때 편하다.
Map<String, List<Points>> map = new HashMap<String, List<Points>>();
위 처럼 자료형 명세를 중복하면, 형인자가 늘어남에 따라 길고 복잡한 코드가 만들어진다.
하지만 팩토리 메서드를 사용한다면
public static <K, V> HashMap<K, V> newInstance(){
return new HashMap<K, V>();
}
Map<String, List<Points>> map = HashMap.newInstance();
위 처럼 좀 더 간결하게 작성이 가능하다.
팩토리 메서드 이름짓기
현업에서 이름은 보통 다음과 같은 것을 사용한다.
- valueOf : 형변환 메서드로, 인자로 주어진 값과 같은 값을 갖는 객체를 반환한다는 뜻.
- of : valueOf 의 축약
- getInstance : 인자의 값을 갖는 객체를 반환하지만, 인자와 같은 값을 갖지 않을 수도 있다. 싱글턴 패턴을 따르는 경우, 인자 없이 항상 같은 객체를 반환한다.
- newInstance : getInstance 와 같지만 호출 시마다 다른 객체를 반환한다.
- getType : getInstance 와 같지만, 반환될 객체의 클래스와 다른 클래스에 팩토리 메서드가 있을 때 사용한다. Type은 팩토리 메서드가 반환할 객체의 자료형이다.
- newType : newInstance와 같지만, 반환될 객체의 클래스와 다른 클래스에 팩토리 메서드가 있을 때 사용한다. Type은 팩토리 메서드가 반환할 객체의 자료형이다.
나는 팩토리 메서드의 존재 조차 모르고 살다가 코드스쿼드
에 와서 Pobi 에게 배우면서 알게 되었는데, 처음에는 생소해서 위 질문처럼 의문점을 가졌었는데 직접 써보다 보니까 점점 팩토리 메서드의 진가를 알게 되는 것 같다.
팩토리 메서드는 보통 생성자가 2개 이상인 경우에 많이 사용하고, 의도를 구분해주는 역할로 사용한다.
이외에 팩토리 클래스도 있는데, 팩토리 클래스는 내가 아닌 다른 클래스 인스턴스를 생성해주는 로직을 가지는 클래스를 말하며, 인스턴스 생성하는 로직이 복잡한 경우에 사용한다.
예를 들면 좌표를 입력받아 좌표의 개수에 따라서 삼각형 또는, 사각형의 넓이를 구하는 좌표 계산기 프로그램을 만들 때, 팩토리 클래스를 이용해서 구현할 수 있다.
ex) Triangle 클래스, TriangleFactory 클래스 (Triangle 객체를 생성하는 팩토리 메서드를 담고있다.)
'Java' 카테고리의 다른 글
[이펙티브 자바] 아이템 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2021.05.31 |
---|---|
LinkedList (0) | 2021.05.30 |
[이펙티브 자바] 아이템 2. 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2021.05.25 |
[이펙티브 자바] 아이템1. 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2021.01.23 |
JVM (Java Virtual Machine) (2) | 2019.06.26 |
댓글