생성자 대신 정적 팩토리 메서드를 고려하라
// 정적 팩토리 메소드 ex
public class Person {
private final String name;
private final int age;
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public static Person of(String name, int age) {
return new Person(name, age);
}
}
클라이언트가 클래스의 인스턴스를 얻는 전통적인 수단은 public 생성자 이다.
하지만 클래스는 public 생성자와 대신 (혹은 생성자와 함께) 정적 팩터리 메서드를 제공할 수 있다.
생성자에 넘기는 매개변수와 생성자 만으로는 반환될 객체의 특성을 제대로 파악하기 힘들다.
그러나 정적 팩터리는 네이밍이 가능함으로 반환될 객체의 특성을 쉽게 파악할 수 있다.
public class Car {
private final String brand;
private Car(String brand) {
this.brand = brand;
}
public static Car brandFrom(String brand) {
return new Car(brand);
}
}
불변클래스는 인스턴스를 미리 만들어 놓거나 새로 생성한 인스턴스를 캐싱하여 재활용하는 식으로
불필요한 객체 생성을 피할 수 있다.
enum과 같이 자주 사용되는 요소의 개수가 정해져있다면 해당 개수만큼 미리 생성해놓고
조회(캐싱)할 수 있는 구조로 만들수 있다.
정적 팩터리 메서드와 캐싱구조를 함께 사용하면 매번 새로운 객체를 생성할 필요가 없어진다.
즉, 객체 생성 비용이 큰 객체가 자주 생성된다면 성능상 이점을 볼 수 있다.
public class LottoNumber {
private static final int MIN_LOTTO_NUMBER = 1;
private static final int MAX_LOTTO_NUMBER = 45;
private static Map<Integer, LottoNumber> lottoNumberCache = new HashMap<>();
static {
for (int i = MIN_LOTTO_NUMBER; i < MAX_LOTTO_NUMBER; i++) {
lottoNumberCache.put(i, new LottoNumber(i));
}
}
private int number;
private LottoNumber(int number) {
this.number = number;
}
public LottoNumber from(int number) {
return lottoNumberCache.get(number);
}
}
상속을 사용할 때 확인할 수 있다.
클라이언트에게 구현체를 노출하지 않고 반환할 수 있고 결국 API의 개념적 무게가 가벼워 진다.
public static Grade of(int score) {
if (score < 70) {
return new Fail;
}
if (score > 70) {
return new Pass;
}
}
class Fail extends Grade {}
class Pass extends Grade {}
인스턴스 통제 클래스를 구현하기 위해서는 new 키워드를 사용하여 임의로 객체를 생성함을 막아야한다.
이를 위해 생성자의 접근 제어자를 private 로 설정해야하는데, 생성자가 private 인 클래스는 상속을 할 수 없다. 즉, 부모 클래스가 될 수 없다.
이 제약은 컴포지션을 사용하도록 유도하고 불변타입으로 만들려면 이 제약을 지켜야 한다는 점에서 오히려 장점으로 받아들여 진다.
from
: 하나의 매개 변수를 받아서 객체를 생성of
: 여러개의 매개 변수를 받아서 객체를 생성getInstance
& instance
: 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음.newInstance
& create
: 새로운 인스턴스를 생성get[OtherType]
: 다른 타입의 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음.new[OtherType]
: 다른 타입의 새로운 인스턴스를 생성.