[디자인 패턴] Abstract Factory 패턴 (관련 부품을 조합해서 제품 만들기)

트레드링스

참고 : JAVA 언어로 배우는 디자인 패턴 입문


안녕하세요. 물류 플랫폼 TRADLINX 개발팀 양갱 입니다.

지난 시간에 디자인 패턴을 사용하는 이유를 알아봤는데요.

(지난 이야기) 디자인 패턴을 사용하는 이유가 반복적인 코드는 줄이고 
코드를 보다 효율적으로 관리하기 위한 구조로 만드는 것이라고 했습니다. (Builder 패턴 참고)


자 그럼 오늘은 디자인 패턴중의 하나인 Abstract Factory 패턴에 대해 알아보도록 하겠습니다.
저는 처음 이 패턴의 이름을 들었을때,


지금은 고전게임이 되어버린 스트크래프트의 팩토리가 떠올랐습니다. (아재스멜... 킁킁)

스타크래프트를 잘 모르셔도 Factory 라는 의미는 잘 아실텐데요.

바로 '공장' 이라는 뜻입니다!!!

그렇다면, 공장은 무엇을 하는 곳이죠?
바로, 여러가지 부품을 조립하여 물건을 만들어내는 곳입니다.

이것이 바로 Abstract Factory 패턴의 핵심입니다!!! 별거 아뉘죠~

"근대 양갱 Abstract는 왜 붙은거야?" 라고 물으시는 분! 귯귯!

Abstract의 의미를 사전에서 찾아보면 '추상적인' 이라는 뜻이 있습니다.

'추상적인 공장' 이게 또 뭔소리지?'

당황하지 마시고 Abstract Factory 패턴에서는 '추상적인 공장' 뿐만 아니라 '추상적인 제품' 이나 '추상적인 부품'도 등장하기 때문입니다. 추상적인 공장에서 추상적인 부품을 조립해서 추상적인 제품을 만듭니다.

도대체 무슨 X소리냐?  워워.. 진정하세요.


우리가 알고있는 오브젝트(객체)지향에서 '추상적'이란 단어의 의미를 떠올려 보겠습니다.
'추상적이다' 라는 단어는 '구체적으로  어떻게 구현되어 있는지에 대해서는 생각하지 않고, 인터페이스(API)만을 생각'하는 것이라 의미입니다. 

예를들어, 추상메소드(Abstract Method)는 메소드 본체는 기술되어 있지 않고 이름과 매개변수만이 정해져 있는 함수입니다.  


Abstract Factory 패턴에서는 추상적인 공장이 등장하고, 추상적인 부품을 조립해서 추상적인 제품을 만듭니다.
즉, 부품의 구체적인 구현에는 주목하지 않고 인터페이스(API)에 주목합니다. 그리고 인터페이스(API)만을 사용해서 부품을 조립하고 제품으로 완성합니다.


이 말을 기억하시고, 이전에 얘기했듯이 처음부터 나무에 집중하지 마시고 숲을 먼저 파악하겠다는 마음으로 접근하시면 보다 쉽게 이해하실 수 있으실 겁니다.

본격적으로 Abstract Factory 패턴에 들어가기에 앞서, 이번에 살펴볼 예제는 계층구조를 가진 Html 페이지 만들기 입니다.

실행방법:

결과:

 
이 예제 프로그램은 다음과 같은 세 개의 패키지로 분리된 구성되어 있습니다.
~ factory 패키지 : 추상적인 공장, 제품, 부품을 포함한 패키지
~ main 패키지 : Main 클래스를 포함한 패키지
~ listfactory 패키지 : 구체적인 공장, 제품, 부품을 포함한 패키지



전체적인 구조를 살펴보겠습니다.


처음보면 낙서같이 보이지만, 의미를 이해하고 보시면 쉽게 눈에 들어오실꺼에요.

그럼 소스코드를 살펴볼까요. 
먼저, 추상적인 것들부터 살펴보겠습니다.

Item 클래스는 Link와 Tray의 상위클래스 입니다. 즉, Link와 Tray는 부품으로 Item이란 걸로 동일시하기 위한 클래스입니다.


Page 클래스는 HTML 페이지 전체를 추상적으로 표현한 클래스 입니다. Link나 Tray가 추상적인 '부품' 이라면
Page는 추상적인'제품'에 해당합니다. 페이지에는 add 메소드를 사용해서 Item(Link 또는 Tray) 를 추가합니다.
Link와 Tray를 Item 하나로 동일시해서 다루는 것에 집중하시기 바랍니다.

output 메소드는 안에서는 제목을 기초로 파일명을 결정하고 makeHtml의 메소드를 사용해서 자신의 HTML의 내용을 파일에 기술하고 있습니다.


드디어 추상적인 공장입니다.  getFactory 메소드의 안에서는 구체적인 공장의 인스턴스를 만들지만(예: ListFatory) 반환값은 추상적인 공장이라는 점에 주의해서 보시기 바랍니다.

createLink, createTray, createPage의 각 메소드는 추상적인 공장에서 부품이나 제품을 작성할때 이용하는 메소드입니다. 이것은 모두 추상 메소드로 되어 있고, 실제로 구체적인 부품이나 제품을 만드는 것은 하위 클래스인 구체적인 공장에게 맡기고 있습니다.

자 이제 추상적인것은 그만보고, 실제 공장에 주문을 하는 사람 Main을 살펴볼까요.


공장에 주문을 하는 사람(Main 클래스) 이 어떤 공장에 주문을 하는지 살펴보세요. 추상적인 공장에 주문을 하고 있습니다.
하지만, getFacory로 만들어 지는 공장은 구체적인 공장이라는 점을 잊지마세요.

이제는 실제로 일하는 구체적인 녀석들을 살펴보겠습니다.


ListLink 클래스(구체적인 부품)는 Link 클래스(추상적인 부품)의 하위 클래스 입니다.

아마도 구현해야하는 메소드가 있었죠?
맞아요. 상위 클래스에서 추상 메소드였던 makeHTML 입니다.

ListLink에서는

  • 태그와 태그를 사용해서 HTML의 일부분을 작성하고 있습니다. 왜냐면? 부품이니까요.

    ListTray 클래스는 Tray 클래스의 하위 클래스입니다. 여기에서 makeHTML 이 어떻게 구현되고 있는지 주목하세요.

    각각의 Item들은 어떻게 HTML화하는 것일까요?
    물론 각각 Item(Link 또는 Tray)의 makeHTML을 호출해야 합니다. 변수 item의 내용이 실제로 ListLink의 인스턴지인지 ListTray의 인스턴스인지를 신경 쓸 필요는 없습니다.

    단지, 간단하게 ite
    m.makeHtml() 로 끝내버리내요ㅎㅎ

    여기에서 변수 item의 내용이 실제로 무엇인지를 조사해서 프로그램을 작성해서는 안됩니다. 그건 매우 비오브젝트 지향적인 프로그램이 되어 버립니다. 아까 List와 Tray를 Item이라는 클래스로 동일시한 이유가 여기에 있습니다!

    변수 item은 Item 형이고 Item 클래스에는 makeHTML()이라는 메소드가 선언되어 있습니다. 그리고 ListLink와 LiskTray 모두 Item 클래스의 하위 클래스입니다. 그러므로 그냥 makeHTML 메소드를 호출하여 사용하면 됩니다.

    남은것은 item이 makeHTML() 메소드를 조화롭게 처리해 주는 것입니다. 어떻게 처리하는 지는 item이라는 하나의 오브젝트가 알고 있습니다. 이것이 객체지향의 이점입니다!

    구체적인 제품이 만들어지는 과정입니다. (스타크래프트 Factory 에서 시저탱크를 뽑는거죠 감격ㅠㅜ)
    while문을

      ...
    로 표현한  이유를 아시겠나요?

    이것은 while문의 내부에서 append 되는 item.makeHTML()의 출력결과가
      의 내부에 포함되는 것은 전제로 하기 때문입니다.

      ListLink나 TrayLink의 makeHTML()를 다시 살펴보세요. 반드시
    • 태그가 바깥에 나오고 있죠.
      굳이 표현하자면, 볼트와 너트처럼 이어지는 부분입니다.


      여러분, 여기까지 오시느라 고생하셨습니다.
      자, 그러면 여기서 질문하나, Q. 새로운 구성의 페이지를 만들려면 어떻게 해야할까요?

      네 그렇습니다! 구체적인 공장과, 구체적인 제품, 구체적인 부품만 다시 만들면 됩니다.

      BUT, 부품을 새롭게 추가하는 것은 곤란합니다.
      예를들어, factory 패키지에 Picture라는 부품을 추가했다고 가정한다면, 
      이미 존재하는 구체적인 공장 전부에 Picture에 대응하는 수정을 해야 합니다. listfactory 패키지라면,

      ~ ListFactory 클래스에 createPicture 메소드를 추가
      ~ 새롭게 ListPicture 클래스를 작성

      만들어 놓은 공장이 많으면 많을수록 고된 작업이 될것입니다..

      자 그럼, 새로운 공장을 지어볼까요^^ 새로운 공장에서는 아래와 같은 페이지(제품)를 만드는 곳이에요.
      이와 관련된 내용은 소스코드만 제공하도록 하겠습니다. 

      그리고 꼭! 새로운 공장을 추가해보길 바랍니다!
      끝까지 읽고 공장을 추가하신 분께 드리고 싶은 말이 마지막에 있습니다.


      여러분은 지금까지 추상적인 공장을 지어서 추상적인 부품을 조립해서 추상적인 제품을 만들어 냈습니다.

      이게 Abstract Factory 패턴입니다.

      이제 이런 공장 몇백개 몇천개 만들 수 있겠죠?

      여러분은 모두 멋진사람들 입니다.

  • 기업문화 엿볼 때, 더팀스

    로그인

    /