참고 - Effective Java Item 1
Effective Java의 정적 팩토리 메서드 패턴
정적 팩토리 메서드는 객체 생성을 위한 유용한 패턴으로, 다음과 같은 장점이 있습니다.
장점
1. 이름을 가질 수 있다: 생성자는 클래스와 동일한 이름을 써야 하지만, 정적 팩토리 메서드는 의도를 명확히 표현하는 이름을 지을 수 있다는 장점을 가진다.
public class Pizza {
private int size;
private boolean cheese;
private boolean pepperoni;
private Pizza(int size, boolean cheese, boolean pepperoni) {
this.size = size;
this.cheese = cheese;
this.pepperoni = pepperoni;
}
// 정적 팩토리 메서드들
public static Pizza createCheesePizza(int size) {
return new Pizza(size, true, false);
}
public static Pizza createPepperoniPizza(int size) {
return new Pizza(size, true, true);
}
}
// 사용 예
Pizza cheesePizza = Pizza.createCheesePizza(12);
Pizza pepperoniPizza = Pizza.createPepperoniPizza(14);
2. 호출될 때마다 새로운 인스턴스를 생성하지 않아도 된다 : 불변 클래스(Immutable class)의 경우 미리 생성된 인스턴스를 캐싱하여 재활용할 수 있다.
public class Boolean {
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
private final boolean value;
private Boolean(boolean value) {
this.value = value;
}
public static Boolean valueOf(boolean b) {
return b ? TRUE : FALSE;
}
}
// 사용 예
Boolean true1 = Boolean.valueOf(true); // 캐시된 TRUE 인스턴스 반환
Boolean true2 = Boolean.valueOf(true); // 동일한 인스턴스 반환
System.out.println(true1 == true2); // true
3. 반환 타입의 하위 타입 객체를 반환할 수 있다 : 인터페이스를 반환 타입으로 사용하면 실제 구현체를 감출 수 있다.
public interface Animal {
void makeSound();
}
public class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}
public class AnimalFactory {
public static Animal createAnimal(String type) {
if (type.equalsIgnoreCase("dog")) {
return new Dog();
} else if (type.equalsIgnoreCase("cat")) {
return new Cat();
}
throw new IllegalArgumentException("Unknown animal type");
}
}
// 사용 예
Animal dog = AnimalFactory.createAnimal("dog");
Animal cat = AnimalFactory.createAnimal("cat");
4. 입력 매개변수에 따라 다른 클래스의 객체를 반환할 수 있다 : 다양한 입력에 따라 적절한 객체를 생성할 수 있다.
public interface PaymentStrategy {
void pay(int amount);
}
public class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card");
}
}
public class PayPalPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal");
}
}
public class PaymentFactory {
public static PaymentStrategy getPaymentMethod(String paymentMethod) {
if (paymentMethod.equalsIgnoreCase("CREDIT_CARD")) {
return new CreditCardPayment();
} else if (paymentMethod.equalsIgnoreCase("PAYPAL")) {
return new PayPalPayment();
}
throw new IllegalArgumentException("Unknown payment method");
}
}
5. 정적 팩토리 메서드 작성 시점에 반환할 객체의 클래스가 존재하지 않아도 된다 : 서비스 제공자 프레임워크의 근간이 되는 유연한 설계가 가능하다.
public interface DataSource {
Connection getConnection();
}
// 서비스 제공자 인터페이스
public interface DataSourceProvider {
DataSource createDataSource();
}
public class DataSourceFactory {
// 제공자 등록 API
public static void registerProvider(String name, DataSourceProvider provider) {
providers.put(name, provider);
}
// 서비스 접근 API
public static DataSource getDataSource(String name) {
DataSourceProvider provider = providers.get(name);
if (provider == null)
throw new IllegalArgumentException("No provider registered for " + name);
return provider.createDataSource();
}
private static final Map<String, DataSourceProvider> providers = new HashMap<>();
}
단점
1) 정적 팩터리만 제공하면 하위 클래스를 만들 수 없다.
2) 정적 팩터리 메소드는 프로그래머가 찾기 어려워서 관례를 주로 따른다. (of, from ...etc)
'자바' 카테고리의 다른 글
자바 - 싱글턴 패턴 (0) | 2024.11.25 |
---|---|
자바 - 빌더 패턴 (0) | 2024.11.25 |
자바 - 정규화 표현 문법 (0) | 2024.11.24 |
자바 JVM - 힙 영역과 GC (0) | 2024.11.23 |
자바 JVM - 런타임 데이터 영역 (0) | 2024.11.23 |
댓글