반응형
Abstract Factory Pattern (추상 팩토리 패턴)
목적
서로 관련성이 있거나 독립적인 여러개의 객체들(Product)을 하나의 카테고리로 묶어서 팩토리를 통해 생성한다.
Product 객체들과 팩토리를 추상화하여 사용자에게 인터페이스를 제공한다.
<출처 위키백과>
사용 시나리오
사실 UML이나 디자인패턴의 의도를 읽어보아도 언제 디자인 패턴을 사용해야할지 공감하기는 쉽지 않다.
따라서 현실에서 예를 들어 아래와 같은 기능을 만든다고 가정해보면
- 팝업창에 스크롤이 하나 달려있는 GUI 프로그램을 만들려고 한다.
- GUI는 OS(플랫폼)에 따라 다르게 생성되어야 한다.
이러한 경우 추상 팩토리 패턴을 활용하여 OS별로 GUI를 만들어 주는 팩토리와 스크롤,팝업창을 만들면 된다.
거기에 추가적으로 팩토리들을 추상화 하고 각각의 부품들(스크롤, 팝업창)까지 추상화를 통해 구현하면 main함수(사용자)쪽의 코드는 수정없이 OS가 변경 되더라도 수정이 필요없게 된다.
Popup과 Scroll의 추상 클래스를 기준으로 Mac과 Window에서 각각 사용 되는 Popup과 Scroll을 만들어보면
(최대한 간단히!)
(Popup과 Scroll 클래스는 위의 UML상의 AbstractProduct에 해당, WinPopup, WinScroll, MacPopup, MacScroll은 Product에 해당한다.)
[Abstract Product]
class Popup { //Popup 추상 클래스 public: virtual void showPopup() = 0; }; class Scroll { //Scroll 추상 클래스 public: virtual void showScroll() = 0; };
[Product]
class MacPopup : public Popup { public: virtual void showPopup() { cout<<"This is Mac Popup"<<endl; } }; class WinPopup : public Popup { public: virtual void showPopup() { cout<<"This is Win Popup"<<endl; } }; class MacScroll : public Scroll { public: virtual void showScroll() { cout<<"This is Mac Scroll"<<endl; } }; class WinScroll : public Scroll { public: virtual void showScroll() { cout<<"This is Win Scroll"<<endl; } };
[Abstract Factory]
class GUIFactory { public: virtual Popup * makePopup() = 0; virtual Scroll * makeScroll() = 0; };
[Concrete Factory]
class MacGUIFactory : public GUIFactory { public: virtual Popup * makePopup() { return new MacPopup(); } virtual Scroll * makeScroll() { return new MacScroll(); } }; class WinGUIFactory : public GUIFactory { public: virtual Popup * makePopup() { return new WinPopup(); } virtual Scroll * makeScroll() { return new WinScroll(); } };
위의 코드로 이제 팩토리와 재료들은 모두 준비되었다. 사용자(main) 코드를 보면 추상팩토리 패턴을 다음과 같이 이용할 수 있게된다.
현재 사용자의 OS가 무엇인지 알수있는 API가 존재한다고 가정할 때 사용자 쪽에서는 OS가 변경 되더라도 코드 변경이 없다.
[사용 예]
class FactoryInstance { public: static GUIFactory* getGuiFacByOS() { int currentOS = getCurrentOS(); //현재 OS가 무엇인지 알아올 수 있는 시스템 API가 있다고 가정합시다. switch(currentOS) { case MAC: return new MacGUIFactory(); case WIN: return new WinGUIFactory(); default: assert("error"); } } }; int main(void) { GUIFactory * factory = FactoryInstance.getGuiFacByOS(); Scroll = factory->makeScroll(); Popup = factory->makePopup(); return 0; }
반응형
'Design Patterns > Creational Patterns' 카테고리의 다른 글
Singleton Pattern (C++) (0) | 2019.09.28 |
---|---|
Prototype Pattern (C++) (0) | 2019.09.13 |
Builder Pattern (C++) (0) | 2019.08.24 |
Factory Method Pattern (C++) (0) | 2019.02.06 |
Creational Pattern (생성 패턴) (0) | 2018.11.11 |