생성자 대신 객체 생성을 담당하는 static 메서드
public static 클래스명 of(...) 같은 메서드를 통해 객체를 생성1. 이름을 가질 수 있어 의도가 명확함
Lotto.createAutoLotto();
Lotto.createManualLotto(list);
new Lotto(...)는 어떤 생성인지 의도를 파악하기 어려움2. 호출할 때마다 새로운 객체를 생성할 필요가 없음
private static Map<Integer, LottoNumber> cache = new HashMap<>();
// 미리 캐싱된 객체 반환
public static LottoNumber of(int number) {
return cache.get(number);
}
3. 하위 타입을 반환할 수 있음
public static Level of(int score) {
if (score < 50) return new Basic();
else if (score < 80) return new Intermediate();
else return new Advanced();
}
4. 객체 생성을 캡슐화 할 수 있음
public static CarDto from(Car car) {
return new CarDto(car.getName(), car.getPosition());
}
| 항목 | 생성자 (new) | 정적 팩토리 메서드 |
|---|---|---|
| 이름 | ❌ 없음 | ✅ 있음 (의도 명확) |
| 객체 재사용 | ❌ 불가 | ✅ 가능 (캐싱, 싱글턴 가능) |
| 하위 타입 반환 | ❌ 불가 | ✅ 가능 |
| 캡슐화 (내부 은닉) | ❌ 내부 구현 드러남 | ✅ 내부 숨김 가능 |
| 가독성 | ❌ 목적 파악 어려움 | ✅ 이름만으로도 의도 명확 |
| 확장성 | ❌ 제한적 | ✅ 유연한 변경 가능 |
| 메서드 이름 | 의미 |
|---|---|
of(...) | 여러 인자를 받아 객체 생성 |
from(...) | 하나의 인자로부터 객체 변환/생성 |
getInstance() | 동일한 인스턴스를 반환할 수도 있음 |
instance() | 위와 동일 |
newInstance() | 항상 새로운 인스턴스 반환 |
create() | 항상 새로운 객체 생성 |
getXxx() | 다른 타입 객체 반환 (캐싱 가능) |
newXxx() | 새로운 타입의 객체 반환 |
생성자보다 정적 팩토리 메서드는 유연성, 가독성, 재사용성, 캡술화 측면에서 훨씬 유리하다.