티스토리 뷰
[Effective Java] 01. 생성자 대신 정적 팩터리 메서드를 사용할 수 없는지 생각해 보라.
Reference M1 2019. 2. 24. 01:00static factory method
클래스를 통해 객체를 만드는 일반적인 방법은 public으로 선언된 생성자(constructor)를 이용하는 것이다. 그러나 모든 프로그래머가 반드시 알고 있어야 하는 방법이 하나 더 있다. 클래스에 public으로 선언된 정적 팩터리 메서드(static factory method)를 추가하는 것이다.
정적 팩터리 메서드(static factory method)는 디자인 패턴 중 팩터리 메서드 개념(Factory Method)과 다르다는 점에 유의하자.
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
위 코드는 실제 Boolean class의 method이다.
장점
- 이름이 있다.
생성자로 전달되는 인자(parameter)들은 어떤 객체가 생성되는지를 설명하지 못하지만, 정적 팩토리 메서드는 이름을 잘 짓기만 한다면 사용하기도 쉽고, 클라이언트 코드의 가독성(readability)도 높아진다.
클래스에는 시그너처(signature) 별로 하나의 생성자만 넣을 수 있다. 이런 제약을 피하는 방법은 인자의 순서를 바꾸는 방법이 있다. 하지만 이 방법은 최악의 발상이다. 하지만 정적 팩토리 메서드를 사용하면 이름이 있으므로 그런 문제가 생기지 않는다.
- 호출할 때마다 새로운 객체를 생성할 필요가 없다.
변경 불가능한 클래스 라면 이미 만들어 둔 객체를 활용할 수도 있고, 만든 객체를 캐시(cache) 해놓고 재사용할 수도 있다. 이 기법은 경량(Flyweight) 패턴과 유사하다. 성능을 크게 개선할 수 있다. 이런 기능을 갖춘 클래스는 개체 통제 클래스(instance-controlled class)라고 한다.
- 생성자와 달리 반환값 자료형의 하위 자료형 객체를 반환할 수 있다.
이 유연성을 활용하면 public으로 선언되지 않는 클래스의 객체를 반환하는 API를 만들 수 있다. 이 기법은 인터페이스 기반 프레임워크(interface-based framwork) 구현에 적합한데, 이 프레임워크 인터페이스는 정적 팩터리 메서드의 반환값 자료형으로 이용된다. 메서드에 주어지는 인자를 이용하여 어떤 클래스의 객체를 만들지도 동적으로 결정할 수 있다. 단지 정적 팩터리 메서드의 반환값 자료형에 부합하기만 하면 된다, 이런 유연성이 유지 보수하거나 성능을 개선하기도 좋다.
이런 장점을 잘 살린 것이 JDBC이다. 정적 팩터리 메서드를 통해 Connection을 하고 내부적으로 어떤 동작을 하는지 전혀 신경 쓰지 않아도 되기 때문이다.
- 형인자 자료형(parameterized type) 객체를 만들 때 편하다.
Map<String, List<String>> m = new HashMap<String, List<String>>();
이런 클래스의 생성자를 호출할 때는, 문맥상 형인자가 명백하더라도 반드시 인자로 형인자를 전달해야 한다. 하지만 정적 팩터리 메서드를 사용하면 컴파일러가 형인자를 스스로 알아내도록 할 수 있다.
Map<String, List<String>> m = new HashMap<>();
자바 1.7부터는 생성자를 호출할 때도 자료형 유추를 사용할 수 있다. <> 기호를 "다이아몬드 연산자(diamond operator)"라고 불리며, 이 기호를 생략하면 경고가 발생한다.
단점
- public이나 protected로 선언된 생성자가 없으므로 하위 클래스를 만들 수 없다.
- 정적 팩터리 메서드가 다른 정적 메서드와 확연히 구분되지 않는다.
API 문서를 보면 정적 팩터리 메서드 인지 정적 메서드 인지 파악하기가 쉽지 않다. 정적 팩터리 메서드의 경우 보통 다음과 같은 이름을 사용한다.
valueOf : 인자로 주어진 값과 같은 값을 갖는 객체를 반환한다.
of : valueOf를 더 간단하게 정의
getInstance : 객체를 반환하지만, 인자와 같은 값을 갖지 않을 수도 있다. 싱글턴 패턴을 경우, 인자 없이 항상 같은 객체를 반환한다.
newInstance : getInstance와 같지만 매번 다른 객체를 반환한다.
요약
정적 팩터리 메서드와 public 생성자는 용도가 서로 다르며, 그 차이와 장단점을 이해하는 것이 중요하다. 무조건 생성자를 통해서 객체를 만들기보다는 정적 팩터리 메서드를 고려하자.
'프로그래밍 > Effective Java' 카테고리의 다른 글
[Effective Java] 06. 유효기간이 지난 객체 참조는 폐기하라. (0) | 2019.04.21 |
---|---|
[Effective Java] 05. 불필요한 객체는 만들지 마라. (0) | 2019.03.26 |
[Effective Java] 04. 객체 생성을 막을 때는 private 생성자를 사용하라. (0) | 2019.03.10 |
[Effective Java] 03. private 생성자나 enum 자료형은 싱글턴 패턴을 따르도록 설계하라. (0) | 2019.03.09 |
[Effective Java] 02. 생성자 인자가 많을 때는 Builder 패턴 적용을 고려하라. (0) | 2019.03.01 |
- Eclipse
- React
- SQL
- effective java
- 제주도 여행
- 오라클
- 소프트웨어공학
- 성능분석
- javascript
- 개발환경
- 회고
- sort algorithm
- spring
- Maven
- Linux 명령어
- 이직
- 경력관리
- 리액트
- 정렬 알고리즘
- 프로그래머
- 제주도 3박4일 일정
- 자바스크립트
- Java
- Tomcat
- 리눅스 명령어
- 프로그래머스
- 오라클 내장 함수
- Collection
- 리액트 16
- 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |