📚개발지식/디자인패턴

[디자인패턴] 생성 패턴 - 팩토리 메서드 패턴 (Factory Method Pattern)

뉴발자 2024. 2. 6.
728x90

 

 

 

 

 

 

 

 

 

 

 

 

 

 

그림 1. 팩토리 메서드

 

 

팩토리 메서드 패턴이란?

디자인 패턴의 생성 패턴 중 하나이다.

 

객체 생성을 공장 클래스로 캡슐화 처리하여 생성하게 하는 생성 디자인 패턴이다.

 

쉽게 말하면 사용자가 직접 new 연산자를 사용해 객체를 생성하지 않는다.

 

공장 클래스를 만들고, 이를 상속받는 서브 공장 클래스의 메서드에서 각각 객체 생성을 책임진다.

 

팩토리 메서드 패턴은 객체를 만들어내는 공장을 만드는 패턴이다.

 

 

팩토리 메서드 특징

 • 객체간의 결합도가 낮아지고 유지보수에 용이하다.

 

 • 객체의 유형과 종속성을 캡슐화해 정보를 은닉 처리할 수 있다.

 

 • 기존 객체를 재구성하는 대신 기존 객체를 재사용하여 리소스를 절약할 수 있다.

 

 

장점

 • 생성자와 구현 객체의 강한 결합을 피할 수 있다.

 

 • 팩토리 메서드를 통해 객체의 생성 후 공통으로 할 일을 수행하도록 지정해줄 수 있다.

 

 • 캡슐화, 추상화를 통해 생성되는 객체의 구체적인 타입을 감출 수 있다.

 

 • 단일 책임 원칙을 준수한다.

   객체 생성 코드를 한 곳 (패키지, 클래스 등)으로 이동하여 코드의 유지보수가 쉬워져 원칙을 만족한다.

 

 • 개방/폐쇄 원칙을 준수한다.

   기존 코드를 수정하지 않고 새로운 유형의 제품 인스턴스를 프로그램에 도입할 수 있어 원칙을 만족한다.

 

 • 생성에 대한 인터페이스 부분과 생성에 대한 구현 부분을 따로 나누었기 때문에 패키지를 분리하여 여러 개발자가 협업을 통해 개발하기 쉽다.

 

 

단점

 • 각 제품 구현체마다 팩토리 객체들을 모두 구현해주어야하기 때문에 구현체가 늘어날때 마다 팩토리 클래스가 증가하여 서브 클래스 수가 증가한다.

 

 • 코드의 복잡성이 증가한다.

728x90

 

 

팩토리 메서드를 적용한 예제 코드

예제로 장난감 제품을 만드는 로직을 구현한다고 가정해본다.

 

장난감 제품 객체 생성

먼저 장난감 제품의 객체를 생성한다.

public class Toy {
  public String name, color, price;
  
  @Override
  public String toString() {
    return String.format("Toy {name: '%s', color: '%s', price: '%s'}\n", name, color, price);
  }
}

 

로봇 제품 클래스

public class Robot extends Toy {
  public Robot(String name, String color, String price) {
    this.name = name;
    this.color = color;
    this.price = price;
  }
}

 

인형 제품 클래스

public class Doll extends Toy {
  public Doll(String name, String color, String price) {
    this.name = name;
    this.color = color;
    this.price = price;
  }
}

 

 

장난감 공장 객체 생성

다음으로 객체 생성을 담당할 공장 클래스를 작성해준다.

 

자바 8버전 이후에 추가된 인터페이스의 default 메서드와 자바 9버전 이후에 추가된 private 메서드를 통해 인터페이스로 구현해준다.

 

ToyFactory 인터페이스를 생성하고 다음의 코드를 작성해준다.

public interface ToyFactory {
  default Toy orderToy() {
    Toy toy = createToy();
    
    return toy;
  }
  
  Toy createToy();
}

 

로봇 생성 팩토리 클래스

public class RobotFactory implements ToyFactory {
  private static class SingleInstanceHolder {
    private static final RobotFactory INSTANCE = new RobotFactory();
  }

  public static RobotFactory getInstance() {
    return RobotFactory.SingleInstanceHolder.INSTANCE;
  }

  @Override
  public Toy createToy() {
    return new Robot("Robot", "blue", "30,000");
  }
}

 

객체를 사용자가 생성하는 것이 아닌 팩토리에서 객체를 생성하여 리소스의 소모를 줄여준다.

 

자바를 사용하면 가비지 컬렉션에 의해 인스턴스가 자동으로 지워진다.

 

하지만 이런 가비지 값이 늘어나게되면 나중에 객체 제거 과정에서 Stop-the-world 가 일어나게 된다. (프로그램 정지)

 

따라서 각 팩토리 클래스들을 싱글톤화 시켜서 메모리 최적화를 시켜준다.

 

인형 생성 팩토리 클래스

public class DollFactory implements ToyFactory {
  private static class SingleInstanceHolder {
    private static final DollFactory INSTANCE = new DollFactory();
  }

  public static DollFactory getInstance() {
    return DollFactory.SingleInstanceHolder.INSTANCE;
  }

  @Override
  public Toy createToy() {
    return new Doll("Doll", "red", "15,000");
  }
}

 

 

사용자

이제 팩토리를 통해 객체를 생성한 후 전달 받을 사용자 클래스를 작성한다.

 

각 팩토리 클래스 정의한 getInstance() 메소드를 이용해서 객체를 생성하면 된다.

public class Client {
  public static void main(String[] args) {
    Toy doll = DollFactory.getInstance().orderToy();
    System.out.println(doll);

    Toy robot = RobotFactory.getInstance().orderToy();
    System.out.println(robot);
  }
}

 

 

팩토리 메서드 패턴의 적용 (in 자바)

• java.util.Calendar의 getInstance()

 

• java.util.Resource의 getBundle()

 

• java.text.NumberFormat의 getInstance()

 

• java.nio.charset의 forName()

 

• java.net.URL.SteamHandlerFactory의 createURLStreamHandler(String)

 

• java.util.EnumSet의 of()

 

• java.xml.bind.JAXBContext의 createMarshaller() and other similar methods

 

 

참고 사이트

https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9CFactory-Method-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90#java

 

💠 팩토리 메서드(Factory Method) 패턴 - 완벽 마스터하기

Factory Method Pattern 팩토리 메소드 패턴은 객체 생성을 공장(Factory) 클래스로 캡슐화 처리하여 대신 생성하게 하는 생성 디자인 패턴이다. 즉, 클라이언트에서 직접 new 연산자를 통해 제품 객체를

inpa.tistory.com

 

https://refactoring.guru/ko/design-patterns/factory-method

 

팩토리 메서드 패턴

/ 디자인 패턴들 / 생성 패턴 팩토리 메서드 패턴 다음 이름으로도 불립니다: 가상 생성자, Factory Method 의도 팩토리 메서드는 부모 클래스에서 객체들을 생성할 수 있는 인터페이스를 제공하지

refactoring.guru

 

 

 

 

 

 

 

 

 

 

728x90

'📚개발지식 > 디자인패턴' 카테고리의 다른 글

[UML] 클래스 다이어그램 관계  (0) 2024.01.29

댓글