코코코딩공부/JAVA

[JAVA] 정적 팩토리 메소드

Ocean_ 2023. 4. 7. 13:00

들어가며

우테코를 시작하고 난 이후로 정적 팩토리 메소드 라는 말을 많이 들어왔다. 이펙티브 자바 책을 보면 첫 장이 정적 팩토리 메소드인 만큼 한번 쯤 알고 싶었고, 이번 체스 미션에서 사용해보았기에 정리해보려고 한다.


정적 팩토리 메소드 란 ?

우리는 흔히 인스턴스 객체 생성을 하는데 생성자를 사용한다. new ~~() 이런식으로 작성을 하는데 이를 생성자가 아닌 정적(static)메소드로 하는 것을 정적 팩토리 메소드라고 한다.

체스미션에서 사용한 정적 팩토리 메소드이다. 이를 통해 Command를 만들었다.

public static Command of(String command) {
        return validateCommand(command);
    }

정적 팩토리 메소드를 왜 사용하는가 ?

장점

  1. 이름을 갖는다.
    1. 우리가 특정 클래스를 생성하고자 할때 new 키워드를 사용하여 생성한다면 생성자의 내부 구조를 잘 알 필요가 있다. 하지만 정적 팩토리 메소드를 갖게 된다면 메소드 이름에 객체의 생성 목적을 담아낼 수 있다.
  2. 호출 시 마다 새로운 객체를 생성할 필요가 없다.
    1. 인스턴스를 미리 만들어 놓거나, 새로운 인스턴스를 캐싱하는 식으로 불필요한 객체 생성을 피할 수 있다.
  3. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
    1. 반환타입의 하위 타입이기만 하면 어떤 클래스 객체를 반환하든 상관없다.

단점

  1. 상속을 하려면 public이나 protected 생성자가 필요하니 정적 팩토리 메소드만 제공하면 하위 클래스를 만들 수 없다.
  2. 정적 팩토리 메소드는 프로그래머가 찾기 어렵다.

정적 팩토리 메소드와 public생성자는 각자 쓰임새가 다르다. 장단점이 있는데, 정적 팩토리를 사용하는게 유리한 경우가 더 많으므로 무작정 public 생성자를 제공하던 습관이 있다면 고치자.


정적 팩토리 메소드 네이밍 컨벤션

  • from
    • 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환한다.
  • of
    • 여러 매개변수를 받아서 적절한 타입의 인스턴스를 반환한다.
  • valueOf
    • from과 of의 더 자세한 버전이다.
  • instance, getInstance
    • 매개변수로 명시한 인스턴스를 반환하지만, 같은 인스턴스가 아닐 수 있다.
  • create, newInstance
    • 매번 새로운 인스턴스를 생성해 반환한다.
  • getType
    • getInstace와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩토리 메소드를 정의할 때 쓴다.
  • newType
    • newInstance와 같으나, 생성 클래스가 아닌 다른 클래스에 팩토리 메소드 정의할 때 쓴다.

체스 미션에서의 정적 팩토리 메소드 사용기

private Command(String command) {
        this.command = command;
}

public static Command of(String command) {
    return validateStartOrEnd(command);
}

---

모든 기물
private Bishop(Team team) {
        this.team = team;
}

public static Bishop from(Team team) {
    return new Bishop(team);
}

---
좌표
private Point(File file, Rank rank) {
        this.file = file;
        this.rank = rank;
    }

public static Point of(File file, Rank rank) {
    return cache.computeIfAbsent(toKey(file, rank), ignore -> new Point(file, rank));
}

내가 생각하는 사용 시기

  • 상속관계에서 클래스 사이에서 객체간 형변환이 필요한 경우
  • 여러 번의 잦은 객체 생성이 필요할 경우
  • 생성자가 많아진다면
  • 생성자를 private으로 두고 객체 생성시 validate와 같은 어떤 작업을 하고 싶다면

이럴 경우 나는 사용할 것 같다.


나가며

정적 팩토리 메소드가 좋은건 알겠다. 근데 정확하게 언제 어떻게 사용할 것인가에 대한 의문은 아직도 있다. 이는 구현 하면서 생각해봐야겠다…


참고자료

https://tecoble.techcourse.co.kr/post/2020-05-26-static-factory-method/