삽질의 현장/- C++

#022_시(c)시(c)해서 C++?!_ 팩토리 패턴 사용해보기

shovelman 2015. 7. 20. 01:35

안녕하세요 삽잡이 입니다...


이번 시간에는 팩토리 패턴에 대한 예제를 소개해볼까 합니다...

코드가 엉성할 수 있으나

이번 글을 통해 팩토리 패턴에 대한 감을 잡으실 수 있으면 좋겠군요~!


우선 팩토리패턴은 간단하게 생성과 소멸을 하나의 클래스에 몰빵하는 것입니다...

팩토리... 공장...  생각해보세요... 물건들을 찍어내는...

이와 같이 특정 클래스에 대한 객체를 찍어주는 역할을 하는 클래스를 하나 만드는 것입니다...

공장을 세우는 것이지요...


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
 
#pragma once
#include <iostream>
using namespace std;
 
class Unit
{
    friend class Factory;
private:
    Unit(void);
    ~Unit(void);
};
 
 
cs

이처럼 간단한 Unit이라는 클래스를 만들었습니다.
주목해야할 점은 바로 Facotry라는 class에 friend를 걸었다는 것이죠...
friend... 친구... 즉, prviate한 Unit에 Factory 클래스의 접근을 유일하게 허용해주겠다는 뜻이죠...
물론 쌍방향은 아닙니다... Factory만 Unit에 접근할 수있도록 해주는 것이지요...

사실 friend 키워드를 사용하게 된다면, 
상당히 위험하면서 아무도 접근을 하지 못하게 하는 pivate 접근 지정에 대한 신뢰성을 잃게하는 행위입니다...


우선... 다음 코드를 살펴보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
 
#pragma once
#include "Unit.h"
 
class Factory
{
    static Factory factory;
    Unit *product[10];
    int ucnt;
public:
    static Factory *GetSingleton();
    Unit *Order();
private:
    Factory();
    ~Factory();
};
 
 
 
cs

Factory 형태의 정적 변수를 하나 만들었습니다. 혹시 감이 잡히시나요?

맞습니다.. 바로 싱글톤(Singleton) 패턴을 사용한 것이지요...

한 객체를 통해서만 모든 접근을 할 수 있도록... 그래서 생성자 또한 private로 지정한 것이구요...


해당 헤더의 cpp 파일을 살펴보도록 하겠습니다...


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
 
 
#include "Factory.h"
 
Factory Factory::factory;
 
Factory *Factory::GetSingleton()
{
    return &factory;
}
 
Unit *Factory::Order()
{
    Unit *unit = 0;
    if (ucnt < 10)
    {
        unit = new Unit();
        product[ucnt] = unit;
        ucnt++;
    }
    return unit;
}
 
Factory::Factory()
{
    ucnt = 0;
}
 
 
Factory::~Factory()
{
    for (int i = 0; i < ucnt; ++i)
    {
        delete product[i];
    }
}
 
 
 
cs


하나의 객체만을 생성하기 위해서 정적으로 때려박는(?) 것입니다...

자세한 설명은 아래서 말씀드리도록 하구요... 아무튼...


잘보시면 Order() 메소드에서

Unit class의 객체를 생성하는 일을 수행합니다.

Unit 생성자는 private 접근 지정이 되어있었지만 friend... 즉... 친구죠...

그래서 객체를 생성해줍니다... 찍어주는것이죠... 공장처럼...


중요한 것은 객체의 생성에 대한 임무를 수행했다면,

당연하게 소멸에 대한 책임도 줘야하는 것입니다...

객체의 생성과 소멸을 반드시 책임지게 구현하도록 해주세요!


1
2
3
4
5
6
7
8
9
10
11
12
13
 
 
#include "Factory.h"
void main()
{
    Factory *fac = Factory::GetSingleton();
    Unit *u[10];
    for (int i = 0; i < 10++i)
        fac->Order();
}
 
 
 
cs


자... 이제 싱글톤 패턴에 대해서 설명을 마무리 할 수 있게 되었습니다...

흠... 우리는 지금 싱글톤 패턴이 아닌 팩토리 패턴에 대해서 알아보고 있었는데... 하하...


Factory 클래스 형의 주소를 참조할 수 있는 변수 하나를 만들어 놓고요... (말이 좀 어렵쥬?)

GetSingleton 메소드를 호출합니다...


그렇다면, 정적 멤버로 만들어 둔 단 하나의 객체의 주소를 fac 변수에 저장하는 것이죠...

이렇게 되면 fac 변수를 통해서만 접근할 수 있게 됩니다...

이게 바로 싱글톤 패턴인것이죠...


아무튼...

Unit의 생성자는 private하기 때문에 해당 코드에서 생성할 수는 없으나

Unit 객체를 담기 위한 변수를 선언해뒀습니다...


그리고 fac 변수를 통해 공장에 접근을 하는 것이지요...

그리고 객체 생성을 위해 Order 메소드를 호출함으로써 공장은 바쁘게 움직이기 시작하겠죠...


자... 이게 팩토리 패턴입니다...

특정한 Factory라는 class 에만 접근을 허용하게 해줌으로써 신뢰성을 잃었지만

프로그램 전체로 보자면 오히려 신뢰성이 높아지는 결과를 줄 수 있었습니다.


나무를 보는 것이 아닌 숲을 봤을 때 더욱 효율적일 수 있다 이거죠...

판단은 여러분의 몫! 하하...


아무튼... 인가 받은 특정한 곳에서만 생성할 수 있게 막아둔 것이지요...


논리적인 모순이 발생하지 않도록 방지하기 위해서

특정한 객체의 생성 소멸에 대한 책임을 지는 별도의 클래스를 만들어 주게 된다면

효율적으로 프로그램을 만들 수 있게 됩니다...


그리고... 아까 싱글톤 패턴이 튀어나왔죠...

이처럼 하나의 패턴을 사용할때는 

반드시 하나의 패턴만을 사용해야하는 것은 아닙니다...

다양한 패턴들이 녹여져서 더욱 효율적이고 아름다운 코드가 만들어질 수 있다는 것이죠...


간략하게 팩토리 패턴에 대해서 알아봤습니다...


다음시간에 뵙죠!

이상 삽잡이였습니다!