Intro::
이펙티브 자바 정리본입니다.
클래스는 생성자와 별도로 정적 팩터리 메서드(static factory method)를 제공할 수 있다.
public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; }
정적 팩터리 메서드 장점
- 이름을 가질 수 있습니다.
- 각 생성자가 어떤 역할을 하는지 정확히 기억하는 것보다 쉽게 의도를 파악할 수 있습니다.
- 호출될 때 마다 인스턴스를 새로 생성하지 않아도 됩니다.
- 불필요한 객체 생성 회피합니다.
- 특히 생성 비용이 큰 같은 객체가 자주 요청되는 상황이라면 성능 이점이 존재합니다.
- 정적 팩터리 방식의 클래스를 인스턴스 통제 클래스라고 합니다. 인스턴스 통제를 통해 클래스를 싱글톤으로 만들수도 있고, 인스턴스화 불가로 만들 수 도 있습니다.
- 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있습니다.
- 반환할 객체의 클래스를 자유롭게 선택할 수 있게 하는 유연성을 제공합니다.
- 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
- 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
정적 팩터리 메서드 단점
- 상속을 하려면 public이나 protected 생성자가 필요하니 정적 팩터리 메서드만 제공하면 하위 클래스를 만들 수 없다.
- 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
- 생성자처럼 API 설명에 명확히 드러나지 않으니 사용자는 정적 팩터리 메서드 방식 클래스를 인스턴스화할 방법을 알아내야 한다.
정적 팩터리 메서드 명명 방식 관례
from
: 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환하는 형변환 메서드
of
: 여러 매개변수를 받아 적합한 타입의 인스턴스를 반환하는 집계 메서드
valueOf
: from과 of의 더 자세한 버전
instance
혹은getInstance
: (매개변수를 받는다면) 매개변수로 명시한 인스턴스를 반환하지만, 같은 인스턴스임을 보장하지는 않는다.
create
혹은newInstance
: instance 혹은 getInstance와 같지만, 매번 새로운 인스턴스를 생성해 반환함을 보장한다.
getType
: getInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 때 사용한다.
newType
: newInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 때 사용한다.
type
: getType과 newType의 간결한 버전.
궁금한점
반환할 객체의 클래스가 존재하지 않아도 된다는 게 정확하게 무슨 소리인가??
- 정적 팩토리 메서드를 호출하는 입장에서는 구체적인 클래스의 인스턴스가 반환되는지 알 필요가 없다는 소리입니다. 단지, 반환된 객체가 해당 인터페이스나 추상 클래스를 구현하고 있다는 것만 알고있으면 됩니다.
interface Animal { void makeSound(); } class Dog implements Animal { public void makeSound() { System.out.println("Bark"); } } class Cat implements Animal { public void makeSound() { System.out.println("Meow"); } } class AnimalFactory { public static Animal createAnimal(String type) { if (type.equals("dog")) { return new Dog(); } else if (type.equals("cat")) { return new Cat(); } else { throw new IllegalArgumentException("Unknown animal type"); } } }
인스턴스화 불가인 동반클래스가 정확히 무엇을 의미하는가…??
- 동반 클래스는 주로 인스턴스를 생성할 수 없는 클래스에 대한 동반 역할을 하는 클래스를 의미합니다.
// 인스턴스화 불가능한 주 클래스 public class MainClass { private int value; private MainClass(int value) { this.value = value; } public int getValue() { return value; } // 동반 클래스 public static class Companion { public static MainClass createInstance(int value) { return new MainClass(value); } } } // 사용 예시 public class Main { public static void main(String[] args) { MainClass instance = MainClass.Companion.createInstance(42); System.out.println(instance.getValue()); // 출력: 42 } }
instance 와 create 매개변수를 받는게 잘 이해가 가지 않는다.
- 캐시와 같이 존재하면 해당 객체를, 아니면 새로운 객체를 반환하게끔도 가능하다.
References::
이펙티브 자바 / 조슈아 블로크 지음 (프로그래밍 인사이트)
Loading Comments...