로컬에서는 잘 되는데 ☘️

팩토리 메소드 패턴(Factory Method Pattern)

by youngjun._.

1. 팩토리 메소드 패턴이란?

다양한 구현체 (Product)가 있고, 그 중에서 특정한 구현체를 만들 수 있는 다양한 팩토리(Creator)를 제공할 수 있다.

 

1-1. 정의(Definition)

1-1-1. 팩토리 패턴?

객체의 생성을 캡슐화 하는 패턴이다.

구체적인 객체의 생성 과정을 '팩토리'모듈화 하여 구체적인 부분이 아닌 추상적인 부분에 의존할 수 있도록 한다.

팩토리 패턴에는 팩토리 메소드 패턴추상 팩토리 패턴이 있다.

 

Pattern 공통점 차이점
팩토리 메소드 패턴 객체의 생성부를 캡슐화하여 결합을 느슨하게 함
구체적인 타입에 의존하지 않도록

 상속을 통해 서브 클래스에서 팩토리 메소드를 오버라이딩하여 객체의 생성부를 구현
추상 팩토리 패턴 객체의 집합을 생성하기 위한 정의를 추상체에 위치시키고 하위의 구현체에서 세부적인 집합 생성 과정을 구현
(Fatory Method를 이용해 구현)

 

먼저 팩토리 메소드 패턴을 살펴보자.

 

1-1-2. 팩토리 메소드 패턴?

부모(상위) 클래스알려지지 않은 구체 클래스를 생성하는 패턴이며. 자식(하위) 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴이기도 하다.

출처 : 인프런 백기선님 강의

1-2. 사용 이유

 객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브클래스에서 이루어지도록 하여 재정의 가능한 것으로 설계 하지만, 복잡해지지 않게 한다.

  • 생성할 객체 타입을 예측할 수 없을 때
  • 생성할 객체를 기술하는 책임을 서브클래스에게 정의하고자 할 때
  • 객체 생성의 책임을 서브클래스에 위임시키고 서브클래스에 대한 정보를 은닉하고자 할 때

 

1-3. 장점과 단점

1-3-1. 장점

  • 기존 코드(인스턴스를 만드는 과정)를 수정하지 않고 새로운 인스턴스를 다른 방법으로 생성하도록 확장할 수 있다.
    • Product 와 Creator 간의 커플링(결합)이 느슨함
    • 확장에 열려있고 변경에 닫혀있는 객체지향 원칙을 적용했기 때문에 가능
      • 확장 : 새로운 인스턴스 추가
      • 변경 : 기존 코드를 수정
  • 코드가 간결해진다.
  • 병렬적 클래스 계층도를 연결하는 역할을 담당할 수 있음
✍🏻 팩토리 메소드 패턴을 적용할 때 참고
1. 자바 8의 인터페이스 default 메소드
 - 인터페이스에 추상 메소드가 아닌 default 메소드를 통해 기능을 구현할 수 있게 되어서 상속받는 서브클래스의 중복코드를 제거할 수 있다.
2. 자바 9의 인터페이스의 private 메소드
 - 기능 구현이 가능해지면서 인터페이스의 내부 로직을 private 메소드로 구현하면 읽기 좋은 코드로 작성할 수 있게 된다.

 

1-3-2. 단점

  • 클래스가 많아진다. (클래스 계층도 커질 수 있다.)
    • 제품 클래스가 바뀔 때마다 새로운 서브클래스를 생성해야 한다.
  • 클라이언트가 creator 클래스를 반드시 상속해 Product를 생성해야 한다.

 

1-4. 실제 적용 예시

실제 자바코드에 어떻게 적용되어있는지 예시를 살펴보자.

 

1-4-1. 단순한 팩토리 패턴

매개변수의 값에 따라 또는 메소드에 따라 각기 다른 인스턴스를 리턴하는 단순한 버전 의 팩토리 패턴

java.util.Calendar#getInstance()

public class CalendarExample {
    
    public static void main(String[] args) {
    	log.info("Calendar 예시 : {}", Calendar.getInstance());
    }
}
  • getInstance()를 호출할 때마다 새로운 Calendar 객체가 생성된다.
  • Calendar는 Gregorian형식(우리가 현재 쓰는), Julian 형식이 있는데, 이 두가지 경우를 모두 커버하기 위해 팩토리 메소드 패턴으로 디자인 되었다.

싱글톤(singletone)패턴에서 사용되는 이름 같은데, naming이 약간 잘못 지어진 것 같다.

 

 

java.text.NumberFormat#getInstance()

BeanFactory xmlFactory = new ClassPathXmlApplicationContext("config.xml");
String hello = xmlFactory.getBean("hello", String.class);

BeanFactory javaFactory = new AnnotationConfigApplicationContext(Config.class);
String hi = javaFactory.getBean("hi", String.class);
  • 국가에 따라 또는 화폐에 따라 다른 표현 방식을 커버하기 위해 팩토리 메소드 패턴으로 디자인 되었다.
  • NumberFormat을 구현하는 클래스는 DecimalFormat, ExponentialFormat 등이 있다.

 

1-4-2. 스프링 BeanFactory

Object 타입의 Product를 만드는 BeanFacotry라는 Creator
BeanFactory factory = new XmlBeanFactory(
            new InputStreamResource(
            new FileInputStream("oraclejavacommunity.xml")));
OracleJavaComm ojc = (OracleJavaComm)factory.getBean("oracleJavaBean");
  • xml 설정과 java 설정으로 읽어오는 방식이다.
  • Product에 해당하는 것은 Object
  • ConcreteProduct에 해당하는 것은 xml 또는 class Bean

 

1-5. 결론

팩토리 메소드 패턴을 사용하는 이유는 클래스간의 결합도를 낮추기 위한 것 같다.
결합도라는 것은 간단히 말해 
클래스의 변경할 부분이 생겼을 때 얼마나 다른 클래스에도 영향을 주는가이다. 팩토리 메소드 패턴을 사용하는 경우 직접 객체를 생성해 사용하는 것을 방지하고 서브 클래스에 위임함으로써 보다 효율적인 코드 제어를 할 수 있고 의존성을 제거한다. 결과적으로 결합도 또한 낮출 수 있다.

 

Reference

 

 

블로그의 정보

개발하는만두

youngjun._.

활동하기