💡 개요
오늘은 객체 생성 방식 중 하나인 정적 팩토리 메서드에 대해 정리해 보자.
📕 정적 팩토리 메서드
정적(static) 팩토리(Factory) 메서드(Method)란 말 그대로 static Factory Method를 나타낸다.
메서드는 메서드인데, 객체 생성(팩토리)을 담당하는 정적 메서드라는 것이다.
보통 객체를 생성할 땐 해당 클래스의 생성자를 사용한다.
정적 팩토리 메서드도 마찬가지이다.
하지만 일반적인 생성자 사용 방식과 다른 점은 생성자를 내부에 숨겨 클라이언트가 생성자를 호출하지 못하게 한다.
→ 이러한 점 때문에 클라이언트 코드 수정을 최소화하여 유지보수성을 향상할 수 있다.
그럼 클라이언트 입장에서 객체 생성은 어떻게 하지??
바로 여기서 정적 팩토리 메서드를 사용한다.
다음은 일반 사용자 객체를 생성하는 데, 정적 팩토리 메서드를 사용한 코드이다.
class Member {
private final String email;
private final String password;
private final String nickname;
// private 생성자로 직접 인스턴스화를 막음
private Member(String email, String password, String nickname) {
this.email = email;
this.password = password;
this.nickname = nickname;
}
// 정적 팩토리 메서드 제공
public static Member createGeneralMember(String email, String password, String nickname) {
return new Member(email, password, nickname);
}
}
보다시피 Member 생성자는 접근 제어자가 private 으로 선언되어 있다. 그렇기 때문에 클래스 외부에서 접근하지 못한다.
하지만 createGeneralMember() 메서드는 클래스 내부에 있기 때문에 생성자에 접근할 수 있다.
더군다나 static 으로 선언되어 있기 때문에 Member 객체의 생성과 무관하게 메서드를 사용할 수 있다.
또한 메서드 명을 보면 생성자를 사용할 땐 클래스 명과 생성자 명이 동일해야 하지만, 정적 팩토리 메서드인 createGeneralMember() 을 사용하면 목적을 나타내는 이름을 부여할 수 있기 때문에 가독성이 향상된다.
🚀 정적 팩토리 메서드 명명 방식
from
매개변수를 하나 받아서 해당 타입의 인스턴스를 반환하는 형변환 메서드
public class Color {
private int rgb;
private Color(int rgb) {
this.rgb = rgb;
}
public static Color from(int rgb) {
return new Color(rgb);
}
}
Color color = Color.from(0xFF0000); // 빨간색
of
여러 매개변수를 받아 적합한 타입의 인스턴스를 반환하는 집계 메서드
public class Point {
private int x, y;
private Point(int x, int y) {
this.x = x;
this.y = y;
}
public static Point of(int x, int y) {
return new Point(x, y);
}
public static List<Point> of(Point... points) {
return List.of(points);
}
}
Point p1 = Point.of(3, 5);
List<Point> points = Point.of(Point.of(1, 2), Point.of(3, 4));
valueOf
from과 of의 더 자세한 버전
public class BooleanWrapper {
private boolean value;
private BooleanWrapper(boolean value) {
this.value = value;
}
public static BooleanWrapper valueOf(boolean value) {
return value ? new BooleanWrapper(true) : new BooleanWrapper(false);
}
}
BooleanWrapper bool = BooleanWrapper.valueOf(true);
instance or getInstance
매개변수로 명시한 인스턴스를 반환하지만 같은 인스턴스임은 보장하지 않는다.
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
Singleton instance = Singleton.getInstance();
create or newInstance
instance, getInstance와 같지만 항상 새로운 인스턴스를 생성해 반환함
public class Member {
private String name;
private Member(String name) {
this.name = name;
}
public static Member create(String name) {
return new Member(name);
}
}
Member member1 = Member.create("Alice");
Member member2 = Member.create("Bob");
getType
getInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 때 사용한다.
public class Logger {
private String name;
private Logger(String name) {
this.name = name;
}
public static Logger getLogger(String name) {
return new Logger(name);
}
}
Logger logger = Logger.getLogger("AppLogger");