정적 팩토리 메서드에 대해 학습한 이유
2주 차 코드를 다시 한번 리뷰하면서 문제점을 발견하게 되었습니다. CarName과 같이 원시값 포장한 객체의 경우 검증 로직을 생성자 안에 정의하였는데, 생성자의 책임은 객체를 초기화 하는 것에만 있다는 것을 간과하였습니다. 따라서, 검증 로직에 대한 책임도 가지고 있고 생성자를 만들어 낼 수 있는 방법에 대해 찾게 되었고, 정적 팩토리 메서드를 접하게 되었습니다.
정적 팩토리 메서드란 무엇일까?
- 정적 팩토리 메서드란 쉽게 말해 생성자로 인스턴스를 생성하지 않고, static Method를 사용해 인스턴스를 생성하는 방식입니다.
정적 팩토리 메서드를 사용하는 이유
- 정적 팩토리 메서드를 사용하는 이유는 여러 가지가 있습니다.
1. 이름을 가질 수 있기에 명확한 의도를 전달할 수 있다.
public class Ball {
private final int price;
private Ball(int price) {
this.price = price;
}
public static Ball createSoccerBall() {
return new Ball(20000); // 축구공의 가격
}
public static Ball createBasketball() {
return new Ball(30000); // 농구공의 가격
}
}
- 생성자를 통해 객체를 생성하게 된다면, 가격만 가지고 축구공인지 농구공인지 파악할 수 없습니다. 하지만 이렇게 정적 팩토리 메서드를 이용한다면 어떤 공인지 의도를 명확히 할 수 있습니다.
2. 객체를 캐싱하여 재사용 할 수 있다.
public class Ball {
private static final Ball SOCCER_BALL = new Ball(20000);
private static final Ball BASKETBALL = new Ball(30000);
private final int price;
private Ball(int price) {
this.price = price;
}
public static Ball getSoccerBall() {
return SOCCER_BALL; // 캐싱된 객체 반환
}
public static Ball getBasketball() {
return BASKETBALL; // 캐싱된 객체 반환
}
}
- 축구공과 농구공을 static을 이용해 미리 생성하였습니다. 정적 팩토리 메서드를 사용하면, 이렇게 생성된 객체들을 사용할 수 있습니다.
3. 서브 클래스를 반환할 수 있습니다.
public abstract class Ball {
protected int price;
protected Ball(int price) {
this.price = price;
}
public static Ball createSoccerBall() {
return new SoccerBall(20000);
}
public static Ball createBasketball() {
return new Basketball(30000);
}
}
class SoccerBall extends Ball {
public SoccerBall(int price) { super(price); }
}
class Basketball extends Ball {
public Basketball(int price) { super(price); }
}
Ball.createSoccerBall()
을 호출하면SoccerBall
객체를 반환할 수 있습니다. 해당 예시를 통해 정적 팩토리 메서드가 하위 클래스를 반환할 수 있다는 것을 알 수 있습니다.
4. 객체의 생성 시점, 생성 방법을 제어할 수 있다.
public class Ball {
private final String type;
private final int price;
private Ball(String type, int price) {
this.type = type;
this.price = price;
}
public static Ball createBall(String type, int price) {
if (type == null || type.isBlank()) {
throw new IllegalArgumentException("공 종류는 빈 값일 수 없습니다.");
}
if (price <= 0) {
throw new IllegalArgumentException("공 가격은 음수일 수 없습니다.");
}
return new Ball(type, price);
}
}
- 제가 정적 팩토리 메서드를 학습한 가장 큰 이유입니다. 정적 팩토리 메서드를 통해, 객체 생성 시점을 제어할 수 있습니다.
정적 팩토리 주요 네이밍
of
: 여러 값을 매개변수로 받을 때, 사용됩니다.Ball ball = Ball.of("축구공", 5000);
from
: 하나의 매개변수만 받을 때, 사용됩니다.Ball ball = Ball.from("축구공");
valueOf
: 값에 따라 객체를 반환하거나, 기본 타입에서 객체로 반환할 때 사용됩니다.Ball ball = Ball.valueOf("축구공");
'우아한테크코스[프리코스]' 카테고리의 다른 글
[4주 차] 회고 (1) | 2024.11.12 |
---|---|
[3주 차] 회고 (1) | 2024.11.12 |
[3주 차] TDD (1) | 2024.11.05 |
[2주 차] 상수에 static 선언을 하는 이유에 대하여 - 1주 차 코드리뷰 (3) | 2024.11.05 |
[2주 차] 회고 (1) | 2024.11.05 |