1. 생성자 대신 정적 팩터리 메서드를 고려하라
1. 생성자 대신 정적 팩터리 메서드를 고려하라
아이템 1: 생성자 대신 정적 팩터리 메서드를 고려하라
📌 정적 팩터리 메서드란?
클래스에서 객체를 생성할 때 보통은
new
를 이용하여 생성자를 호출합니다.정적 팩터리 메서드는 생성자 대신 **정적인 메서드(static method)**를 통해 객체를 만들어 반환합니다.
간단한 비교 예시
// 전통적인 생성자 방식
Person person = new Person("John", 25);
// 정적 팩터리 메서드 방식
Person person = Person.fromNameAndAge("John", 25);
📌 정적 팩터리 메서드의 장점
1️⃣ 이름을 가질 수 있다 (명확한 의도 전달)
생성자는 클래스 이름과 같아서, 어떤 의도로 객체를 만드는지 불명확할 때가 있습니다.
팩터리 메서드는 이름으로 객체 생성의 의미를 명확히 할 수 있습니다.
예시
LocalDate date = LocalDate.of(2025, 3, 7); // 명확한 의도를 전달하는 메서드명
2️⃣ 객체 재사용이 가능하다 (성능 개선)
매번 새로운 객체를 만들 필요가 없어서 성능을 개선할 수 있습니다.
이미 만들어진 객체를 재사용(캐싱)할 수 있습니다.
대표적인 예: 자바의
Boolean.valueOf(true)
메서드
예시 코드
public class Person {
private static final Person COLT = new Person("Colt", 28);
private String name;
private int age;
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public static Person getColt() {
return COLT; // 항상 같은 인스턴스를 반환 (재사용)
}
}
// 사용 예시
Person colt1 = Person.getColt();
Person colt2 = Person.getColt();
// colt1과 colt2는 같은 객체이다. (메모리 절약)
3️⃣ 하위 타입 객체를 반환할 수 있다 (유연성)
팩터리 메서드는 자신이 선언한 반환 타입의 하위 타입 객체를 반환할 수 있습니다.
인터페이스의 구현체를 외부에 노출시키지 않고, 상황에 따라 다른 객체를 반환할 수 있습니다.
예시 (Java의 EnumSet)
EnumSet<Color> colors = EnumSet.noneOf(Color.class);
// EnumSet 내부에서 상황에 맞는 RegularEnumSet 혹은 JumboEnumSet을 반환 (사용자는 내부 클래스를 몰라도 됨)
4️⃣ 상황에 따라 다양한 클래스의 객체 반환 가능
입력 매개변수에 따라 각기 다른 객체를 반환하는 로직을 담을 수 있습니다.
반환할 객체의 클래스는 호출 당시 상황에 따라 동적으로 결정됩니다.
예시 코드
public static Animal createAnimal(String type) {
if ("cat".equals(type)) {
return new Cat();
} else if ("dog".equals(type)) {
return new Dog();
}
return null;
}
// 사용 예시
Animal pet = AnimalFactory.createAnimal("cat");
5️⃣ 객체를 생성할 클래스가 꼭 미리 존재할 필요가 없다
서비스 제공자 프레임워크(예: JDBC)는 정적 팩터리를 활용하여, 실제 사용할 클래스를 나중에 정할 수 있도록 유연성을 제공합니다.
이는 프레임워크가 다양한 구현체들을 쉽게 관리할 수 있도록 돕습니다.
대표적 예시 (JDBC)
DriverManager.getConnection()
은 데이터베이스의 종류에 따라 다른 커넥션 객체를 반환할 수 있습니다.
📌 정적 팩터리 메서드의 단점 (주의할 점)
상속을 어렵게 만듦 정적 팩터리 메서드를 사용하려면 생성자가
private
로 설정되기 때문에, 클래스를 상속하기 어려워집니다.찾기 어려울 수 있음 생성자처럼 명확히 드러나지 않아 API 문서를 잘 확인해야 합니다. 이 점은 흔히 쓰는 네이밍 패턴(
from
,of
,valueOf
,getInstance
,newInstance
)으로 완화할 수 있습니다.
📌 정적 팩터리 메서드의 대표적인 네이밍 관례
from
하나의 매개변수를 받아 인스턴스를 반환
Date date = Date.from(instant);
of
여러 매개변수를 받아 인스턴스를 반환
List<String> list = List.of("A","B");
valueOf
기본형 등을 받아 적절한 인스턴스를 반환
Integer i = Integer.valueOf("123");
getInstance
동일한 인스턴스 반환을 보장하지 않음
Calendar cal = Calendar.getInstance();
create
항상 새로운 인스턴스 반환을 보장
Array array = Array.create(5);
newInstance
항상 새로운 인스턴스 생성
Object obj = Class.newInstance();
✅ Nutshell (한눈에 보는 요약)
정적 팩터리 메서드란?
생성자 대신 이름을 가진 정적 메서드를 통해 객체를 생성하는 방식입니다.
장점
✅ 메서드 이름을 통해 명확하게 의도 전달 가능
✅ 객체 재사용을 통해 성능 개선 가능
✅ 하위 타입이나 다양한 클래스 객체를 반환 가능 (유연성)
✅ 서비스 프레임워크 제작 시 유리
단점
⚠️ 상속을 어렵게 할 수 있음
⚠️ 생성자보다 발견하기 어려울 수 있음
📖 한 줄 결론: 정적 팩터리 메서드는 이름과 재사용성을 통해 객체 생성의 명확성, 성능, 유연성을 높이지만, 상속 시에는 신중히 고려해야 합니다.
Last updated