이펙티브 자바:: 아이템 1 <생성자 대신 정적 팩터리 메서드를 고려하라>
🙉

이펙티브 자바:: 아이템 1 <생성자 대신 정적 팩터리 메서드를 고려하라>

Created
Aug 7, 2024 09:36 AM
Last edited time
Last updated August 22, 2024
Tags
Language
Language
Java
URL

Intro::

이펙티브 자바 정리본입니다.
 
클래스는 생성자와 별도로 정적 팩터리 메서드(static factory method)를 제공할 수 있다.
public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; }
 

정적 팩터리 메서드 장점

  1. 이름을 가질 수 있습니다.
    1. 각 생성자가 어떤 역할을 하는지 정확히 기억하는 것보다 쉽게 의도를 파악할 수 있습니다.
  1. 호출될 때 마다 인스턴스를 새로 생성하지 않아도 됩니다.
    1. 불필요한 객체 생성 회피합니다.
    2. 특히 생성 비용이 큰 같은 객체가 자주 요청되는 상황이라면 성능 이점이 존재합니다.
    3. 정적 팩터리 방식의 클래스를 인스턴스 통제 클래스라고 합니다. 인스턴스 통제를 통해 클래스를 싱글톤으로 만들수도 있고, 인스턴스화 불가로 만들 수 도 있습니다.
  1. 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있습니다.
    1. 반환할 객체의 클래스를 자유롭게 선택할 수 있게 하는 유연성을 제공합니다.
  1. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
  1. 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
    1. JDBC를 통한 예시
      JDBC를 통한 예시
 

정적 팩터리 메서드 단점

  1. 상속을 하려면 public이나 protected 생성자가 필요하니 정적 팩터리 메서드만 제공하면 하위 클래스를 만들 수 없다.
  1. 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
    1. 생성자처럼 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...