❐ Description
요즘 대다수가 정적 팩토리 메소드 패턴을 사용한다. 나도 마찬가지로 주로 사용하는데, 거의 대부분
생성자에 대해서 많이 사용하고 있다. 최근에 스터디에서 토의도 했었고, 오랜만에 리마인드 할 겸
정적 팩토리를 씀으로써 얻을 수 있는 장점 그리고 꼭 써야할까에 대한 생각을 정리해보려고 한다.
과거 노션에 정리한 내용 복붙.
❐ 정적 팩토리를 사용해서 얻을 수 있는 이점
1. 이름을 가질 수 있다.
정적 팩터리 메서드는 생성자와 달리 원하는 이름을 붙일 수 있어, 메서드 이름만으로 역할을 설명할 수 있다.
public class User {
private String name;
private String role;
private User(String name, String role) {
this.name = name;
this.role = role;
}
public static User createAdminUser(String name) {
return new User(name, "ADMIN");
}
public static User createGuestUser(String name) {
return new User(name, "GUEST");
}
}
2. 호출될 때마다인스턴스를 새로 생성하지 않아도 된다.
정적 팩터리 메서드는 이미 생성된 인스턴스를 재사용할 수 있으므로, 호출할 때마다 꼭 새로운 객체를
생성할 필요가 없다. 이로 인해 성능이 개선될 수 있다.
public class SampleClass {
private static final Boolean TRUE = Boolean.TRUE;
private static final Boolean FALSE = Boolean.FALSE;
public static Boolean valueOf(boolean value) {
return value ? TRUE : FALSE;
}
}
Boolean.valueOf(true)를 호출하면 항상 동일한 TRUE 객체를 반환하므로, 불필요한 객체 생성을 피할
수 있다. 즉, 매번 새로운 객체를 만들지 않고, 재사용 가능한 객체를 반환하는 방식이다.
3. 반환 타입이 하위 객체를 반환할 수 있다.
public interface Vehicle {
void drive();
}
public class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a car");
}
}
public class Bike implements Vehicle {
@Override
public void drive() {
System.out.println("Riding a bike");
}
}
public class VehicleFactory {
public static Vehicle createVehicle(String type) {
if ("car".equalsIgnoreCase(type)) {
return new Car();
} else if ("bike".equalsIgnoreCase(type)) {
return new Bike();
}
throw new IllegalArgumentException("Unknown vehicle type");
}
}
VehicleFactory.createVehicle("car")는 Vehicle 인터페이스의 하위 타입인 Car 객체를 반환할 수 있고,
필요에 따라 다른 하위 타입인 Bike 객체를 반환할 수도 있다.
4. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환 할 수 있다.
public class ShapeFactory {
public static Shape createShape(String type) {
switch (type) {
case "circle":
return new Circle();
case "rectangle":
return new Rectangle();
case "triangle":
return new Triangle();
default:
throw new IllegalArgumentException("Unknown shape type");
}
}
}
ShapeFactory.createShape("circle")를 호출하면 Circle 객체를 반환하고, "rectangle"을 입력하면
Rectangle 객체를 반환하게 할 수 있다. 이처럼 동일한 메서드로 매개변수에 따라 다른 객체를 반환할 수 있다.
5. 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
public interface Payment {
void pay();
}
public class PaymentFactory {
public static Payment createPayment(String type) {
// 구체적인 구현 클래스가 없는 상태
return null;
}
}
위 코드에서 PaymentFactory.createPayment는 Payment 인터페이스 타입을 반환하도록 설정했다.
이 시점에는 구체적인 클래스가 존재하지 않아도 된다. 나중에 CreditCardPayment나 PaypalPayment 같은
구현 클래스를 만들어 추가할 수 있고, 팩터리 메서드의 반환 객체를 쉽게 변경할 수 있다.
❐ 정적 팩토리 꼭 써야할까?
나의 경우 거의 대부분 1,2번의 경우에만 사용해왔다. 그 중에서도 1번의 이유로 정적 팩토리 메서드를 많이
사용해왔다. 확실히 가독성 측면에서 어떤 목적으로 인스턴스를 만드는 지 한 눈에 띄어서 좋았기 때문이다.
물론 VO를 만들 때 2번의 장점을 얻기 위해서도 정적 팩토리를 사용하곤 했다.
개인적으로 반복되고 귀찮은 작업이더라도, 코드의 가독성과 성능적 이점을 챙기기 위해서 정적 팩토리를
사용하는 게 좋다고 생각한다.
'우테코 7기 > 3주차' 카테고리의 다른 글
과제를 하면서 알게된 사소한 지식들 (0) | 2024.11.04 |
---|---|
Map의 computeXxx 메소드를 알아보자. (0) | 2024.11.03 |
EnumMap을 쓰는 이유 (0) | 2024.11.03 |
3주차 회고 (0) | 2024.11.03 |
로또 (0) | 2024.11.03 |