팩토리 메소드 패턴 vs 추상 팩토리 패턴

반응형
반응형

디자인 패턴을 공부하면서 하나씩 공부할때는 생각보다 쉬운데
여러개를 동시에 공부하거나 다른 패턴을 공부를 해야 되는 상황이라면 헷갈리는 경우가 굉장히 많았다.

디자인 패턴에서는 이러한 양상이 종종 발생이 되며, 
대표적으로 팩토리 메소드 패턴이랑 추상 팩토리 패턴이 존재한다.
이렇게 비슷한 패턴들이 많은 이유는 관점때문이라고 한다. 그러면 이 두개의 패턴은 어떻게 관점이 다른지 확인해보자.

어떻게 보면 두 개모두 팩토리 즉, 공장에서 무언가를 만드는 듯한 느낌을 준다.
그러면 뭐가 다른 걸까?
이름 부터 이 두가지 패턴은 다르다는 느낌을 강력하게 받는다.

처음에 팩토리 패턴을 생각했을 때, 인터페이스 또는 추상 클래스를 통해 만든것을 직접적으로 사용한다고 생각했다.
물론, 이게 맞을 수 있겠지만, 
이 접근은 인터페이스 or 추상 클래스 = 팩토리 패턴이라고 생각할 지도 모르기 때문에 위험한 발상이라고 생각한다.

 아무튼 서론이 길어진 것 같은데 팩토리 패턴과 추상 팩토리를 구현해보면서 생각하면 좋을 것 같다.

이번에도 예제 짜기 귀찮으니 Template라고 대충 만든 다음 진행하려 한다.

팩토리 패턴

public interface TemplateFactory {


  private String random() {
    return UUID.randomUUID().toString();
  }

  default void init(String key) {
    System.out.println(key);
    System.out.println("키값: " + random());
  }

}

대충 이렇게 작성했다.
분명 interface인데 구현체가 존재한다?
그건 바로 자바8,9에 들어온 키워드인 private, default 때문이다. (static 도 있어요)
이들이 생긴 이유는 자바는 다중 상속이 불가능하다는 점에 있다. 
다행스럽게도 이들을 사용함으로써 다중 상속이 가능해졌다.
아무튼 인터페이스를 통해서도 팩토리 패턴을 구현이 가능해졌다.
이제 이것을 사용하면 된다. 
그렇다면 이게 왜 OCP를 지키는 걸까?
내부 구조를 변경하지 않는 이상 더 이상 코드를 변경할 필요가 없어졌다.
만약에 새로운 템플릿?을 추가하고 싶다면

public class Template1 implements TemplateFactory{

  private String name;

  public Template1(String name) {
    this.name = name;
  }

  @Override
  public void init(String key) {
    TemplateFactory.super.init(name +" "+ key);
    System.out.println(name + "제작중");
  }
}

이런식으로 추가하면 된다.

이제 TemplateFactory가 어떻게 되었든 새로운 Template만 추가하면 되기 때문에 OCP를 지켰다고 할 수 있다.
물론, 내부 코드를 수정해야 되는 상황이라면, 그렇게 까지 큰 의미는 없을지도 모르지만..

추상 팩토리 패턴

이 패턴도 팩토리 패턴과 유사하다.
다만 조금 다른점이 있다면, 위 패턴은 상속을 사용해서 구현을 했다면
이 방법은 주 된 방식이 조합을 사용한다.

public interface TemplateFactory {

  Leg createLeg();

  Head createHead();
  
  Body createBody();

}

지금 보이는 Leg, Head, Body가 전부 interface다. 
이제 이것들을 조합해서 사용하면 된다.

public class AntBody implements Body{

}

이런식으로 사용하면 된다.

이것을 다 완성하면

public class AntFactory implements TemplateFactory{

  @Override
  public Leg createLeg() {
    return new AntLeg();
  }

  @Override
  public Head createHead() {
    return new AntHead();
  }

  @Override
  public Body createBody() {
    return new AntBody();
  }
}

이런식으로 사용하면 된다.
개미를 만들었다.
물론 구현 방식은 여러가지가 있을 수 있겠지만, 추상 팩토리는 조합을 이용한 방법이라는 것이라는 걸 말하고 싶었다.

두 개의 공통점은 무언가를 만든다는 점에 있다.
하지만 차이점은 팩토리 (메소드)패턴은 제품을 찍어내는 방법이라면
추상 팩토리 패턴은 하나의 제품을 부품 하나하나 조립해서 만드는 방법이라 생각이 든다.
추상 팩토리 안에 팩토리도 넣을 수 있고
팩토리 안에 추상 팩토리도 넣는건 아무런 문제가 되지 않는다.

 

반응형

'디자인패턴' 카테고리의 다른 글

브릿지 패턴  (0) 2021.11.25
전략 패턴  (0) 2021.11.19
싱글톤 패턴  (0) 2021.11.03
탬플릿 패턴  (0) 2020.06.05
빌더 패턴  (0) 2020.05.27

댓글

Designed by JB FACTORY