Thinking Different







Flyweight Pattern - 플라이웨이트 패턴


  • 데이터를 공유 사용하여 메모리를 절약할 수 있는 패턴이다.
  • 일반적으로 공통으로 사용되는 객체는 새로 생성해서 사용하지 않고 공유를 통해 효율적으로 자원을 활용한다.
  • 한번 생성된 객체는 두번 생성되지 않고, 풀(Pool)에 의해서 관리 및 사용된다.
  • 실제로 가장 많이 사용되는 패턴 중에 하나이다.







샘플 코드)

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
40
41
42
43
44
45
46
47
48
49
50
class Flyweight
{
public:
    virtual void operation() = 0;
};
 
class ConcreteFlyweight : public Flyweight
{
public:
    void operation() override { cout << "ConcreteFlyweight" << endl; }
};
 
class UnsharedConcreteFlyweight : public Flyweight
{
public:
    void operation() override { cout << "UnsharedConcreteFlyweight" << endl; }
};
 
class FlyweightFactory
{
public:
    ~FlyweightFactory() {  }
 
public:
    Flyweight* getFlyweight(int key)
    {
        if (mList.find(key) == mList.end())
        {
            mList[key] = new ConcreteFlyweight;
        }
 
        return mList[key];
    }
 
private:
    map<int, Flyweight*> mList;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    FlyweightFactory flyFactory;
    Flyweight* flyweight = flyFactory.getFlyweight(1);
    flyweight->operation();
 
    getchar();
 
    return 0;
}





예제를 통한 플라이웨이트 패턴(Flyweight Pattern) 알아보기



예제) 아이템 생성 예제


팩토리 패턴은 싱글턴 패턴과 결합하여 사용하고, 팩토리에서는 아이템을 생성하고 풀링(Pool) 관리하도록 하였다. 필요할 때마다 GetItem 함수를 통해서 아이템을 공유 사용할 수 있도록 플라이웨이트 패턴을 구성하였다.


예제 코드)

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#if _UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif
 
#include <map>
 
//------------------------------------------------------------------
// template singleton pattern
template<typename T>
class Singleton
{
protected:
    Singleton() {}
    virtual ~Singleton() {}
    Singleton(const Singleton& s) {}
 
private:
    static void destroy() { delete m_pInstance; }
 
public:
    static T* GetInstance()
    {
        if (m_pInstance == NULL)
        {
            m_pInstance = new T();
            atexit(destroy);
        }
 
        return m_pInstance;
    }
 
private:
    static T* m_pInstance;
};
 
template <typename T> T* Singleton <T>::m_pInstance;
 
 
class Item
{
public:
    virtual void operation() = 0;
};
 
class Potion : public Item
{
public:
    void operation() override { cout << "potion" << endl; }
};
 
class Axe : public Item
{
public:
    void operation() override { cout << "Axe" << endl; }
};
 
class Map : public Item
{
public:
    void operation() override { cout << "Map" << endl; }
};
 
 
class ItemFactory : public Singleton<ItemFactory>
{
public:
    ~ItemFactory() {  }
 
public:
    template<typename T>
    Item* GetItem(int key)
    {
        if (mList.find(key) == mList.end())
        {
            mList[key] = new T;
        }
 
        return mList[key];
    }
 
private:
    map<int, Item*> mList;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Item* potion = ItemFactory::GetInstance()->GetItem<Potion>(1);
    Item* axe = ItemFactory::GetInstance()->GetItem<Axe>(2);
    Item* map = ItemFactory::GetInstance()->GetItem<Map>(3);
 
    potion->operation();
    axe->operation();
    map->operation();
 
    getchar();
 
    return 0;
}


예제 결과)