개발일기

아이템 1 생성자 대신 정적 팩터리 메서드를 고려하라 본문

Effective Java/객체 생성과 파괴

아이템 1 생성자 대신 정적 팩터리 메서드를 고려하라

한둥둥 2022. 9. 14. 12:38

Item 1: 생성자 대신 정적 팩터리 메서드를 고려하라

 

핵심 주제

정적 팩토리 메서드의 장점 5가지

  1. 이름을 가질 수 있다
  2. 두번째, 호출될 때마다 인스턴스를 새로 생성하지는 않아도 된다.
  3. 세 번째, 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다 예시 코드는 아래와 같다.
public class Cat {

   private static Cat cat = null;

   

   private Cat() {}

   public static Cat getInstance() {

      // 초기화

      if(cat == null) {

         cat = new Cat();

      }

      return cat;

   }

}
public interface Shape {

    // Shape interface methods

}



public class Circle implements Shape {

    // Circle implementation

}



public class ShapeFactory {

    public static Shape newCircle() {

        return new Circle();

    }

}

 

4. 네 번째, 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.

// 부모 타입

interface Shape {

    void draw();

}



// 하위 타입: 원

class Circle implements Shape {

    @Override

    public void draw() {

        System.out.println("Drawing a Circle");

    }

}



// 하위 타입: 사각형

class Rectangle implements Shape {

    @Override

    public void draw() {

        System.out.println("Drawing a Rectangle");

    }

}



// 정적 팩토리 메서드를 가진 클래스

class ShapeFactory {

    public static Shape getShape(String type) {

        if ("circle".equalsIgnoreCase(type)) {

            return new Circle();

        } else if ("rectangle".equalsIgnoreCase(type)) {

            return new Rectangle();

        } else {

            throw new IllegalArgumentException("Unknown shape type");

        }

    }

}



// 클라이언트 코드

public class FactoryMethodExample {

    public static void main(String[] args) {

        Shape shape1 = ShapeFactory.getShape("circle");

        shape1.draw(); // Output: Drawing a Circle



        Shape shape2 = ShapeFactory.getShape("rectangle");

        shape2.draw(); // Output: Drawing a Rectangle

    }

}

 

5. 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.

public interface Vehicle {

    void drive();

}



public class VehicleFactory {

    public static Vehicle getVehicle() {

        // 반환 타입만 인터페이스로 정의

        return null; // 초기에는 구체적인 구현이 없어도 메서드 작성 가능

    }

}

 

from : 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환하는 형변환 메서드
of :
여러 매개변수를 받아 적합한 타입의 인스턴스를 반환하는 집계 메서드
valueOf : from
of 자세한 버전
instance
혹은 getInstance: (매개변수를 받는다면) 매개변수로 명시한 인스턴스를 반환하지만, 같은 인스턴스임을 보장하지는 않는다.
create
혹은 newInstance : instance 혹은 getInstance 같지만, 매번 새로운 인스턴스를 생성해 반환함을 보장한다.
getType: getInstance
같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 쓴다. "Type" 팩터리 메서드가 반환할 객체의 타입이다.
newType: newInstance
같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 쓴다. "Type" 팩터리 메서드가 반환할 객체 타입이 아니다.
type : getType
newType 간결한 버전