[Design Pattern] 팩토리 패턴

2016. 1. 30. 04:39프로그래밍/Design Patterns

728x90
728x90

new는 구상 클래스의 객체를 생성 즉 인스턴스를 의미한다.

다형성을 이용해 코딩을 하면 다양한 조건문이 생성되고

이는 프로그래머가 실수할 가능성이 매우 높아진다.

(특히 새 구상 클래스가 설계되었을 시)


심플 팩토리(팩토리 메소드)

예시) 피자가게에서 파는 피자

간단하게 생각할 수 있는 것은 PizzaStore, Pizza 클래스가 필요할 것이다.

Pizza는 CheesePizza 등의 부모 클래스가 되며 다형성을 이용해 이를 생성한다.

피자 스토어는 Pizza 클래스를 이용해 인스턴스를 만들어 내면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Class Pizza
Class A_Pizza : Public Pizza
Class B_Pizza : Public Pizza
 
Class PizzaStore
    String storeName
    String storeNumber
    ...
// 1
    Method OrderPizza(String type)
        IF type is A
            New Instance A_PIZZA
        ELSEIF type is B
            New Instance B_PIZZA
        ELSEIF 
            ...
        IF END
    Method End
// 2
    Method Prepare() Method End
    Method Cup() Mtod End
    ...
 
Class END
cs


수도코드로 작성해보면 대충 이런 꼬라지가 될 것이다.

// 1의 부분의 다형성으로 해당 객체를 생성하는 부분은 굉장히 여러번 수정이 된다.

새로운 구상 클래스가 설계 될 때마다 해당 부분은 수정이 된다. 기존 클래스가 삭제 될때도 물론이다.

// 2의 부분은 PizzaStore의 공통 Method이기 때문에 Method 내부는 변해도 해당 소스가 변하진 않는다.


팩토리 패턴의 기본 컨셉은 이 // 1을 외부로 빼는 것.

아주 기본적이고 효율적인 컨셉이라고 생각한다.


// 1의 부분을 SimpleFactory 클래스로 정의하고 해당 객체가 인스턴스 되는 조건을 받아 인스턴스만 리턴한다.

PizzaStore 클래스는 SimpleFactory의 인스턴스를 가지고 있으면 언제든 호출하여 새로운 Pizza를 만들 수 있다.


책에 Java로 되어있는 수도 코드 비슷한 것들을 C++로 만들어봤다.


2016.02.04 내용추가

진정한 팩토리 패턴(?) 추상 메소드로 구현하기(추상 팩토리)

피자 종류에 따라 피자는 만들 수 있다. 하지만 각 지역에 맞는 고유의 스타일을 제공하려면?

createPizza 메소드를 추상 메소드로 선언해서 이를 구현할 수 있다.


기존 simple 팩토리의 클래스 다이어그램은 이정도가 될 것이다.

(간만에 비주얼 패러다임을 깔아서 직접 그려보았다.)

추상메소드.. 그러니깐 C++에선 가상함수를 이용하여 구현을 하면 된다.

대충 클래스 다이어그램은 이런 느낌.


소스

https://github.com/ElementalKiss/Cpp/tree/master/Source/FactoryPattern


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#pragma once
#include "common.h"
#include "Pizza.h"
 
// base class
class PizzaStore
{
public:
    PizzaStore(void);
    virtual ~PizzaStore(void);
    
    Pizza* orderPizza(const string pizzaType);
 
    // virtual
    virtual Pizza* createPizza(const string pizzaType) = 0;
 
private:
};
 
// derived class
class NYPizzaStore : public PizzaStore
{
public:
    NYPizzaStore();
    ~NYPizzaStore();
 
    virtual Pizza* createPizza(const string pizzaType) override;
private:
};
 
class ChicagoPizzaStore : public PizzaStore
{
public:
    ChicagoPizzaStore();
    ~ChicagoPizzaStore();
 
    virtual Pizza* createPizza(const string pizzaType) override;
private:
};
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "common.h"
 
class Pizza
{
public:
    Pizza(void);
    ~Pizza(void);
 
    // method
    void prepare() { cout<< "Pizza:prepare" << endl; }
    void bake() { cout<< "Pizza:bake" << endl; }
    void cut() { cout<< "Pizza:cut" << endl; }
    void box() { cout<< "Pizza:box" << endl; }    
};
 
// empty class
class CheesePizza : public Pizza { };
class PepperoniPizza : public Pizza { };
class ClamPizza : public Pizza { };
class VeggiePizza : public Pizza { };
cs


이런식으로 하면 피자 가게를 차릴 수 있다.


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

추팩 - 서로 연관되거나 의존적인 객체들로 이루어진 제품군을 생성하기 위한 인터페이스를 제공한다. 

구상 클래스는 서브 클래스에 의해 만들어진다.

팩메 - 객체를 생성하기 위한 인터페이스를 만든다. 인스턴스는 서브클래스에서 결정하도록 한다. 

인스턴스를 만드는 일을 서브 클래스에게 미룰 수 있다.



728x90
반응형

'프로그래밍 > Design Patterns' 카테고리의 다른 글

[Design Pattern] 싱글톤  (2) 2016.02.15
디자인 패턴 연관도  (1) 2015.07.08
중재자 패턴  (2) 2015.05.04
싱글톤 사용하기  (2) 2015.04.21
[Design Pattern] 옵저버 패턴 개요  (0) 2015.04.18
디자인 패턴, 싱글톤, 상태패턴  (2) 2015.04.15