Post List

2015년 1월 4일 일요일

Builder Pattern (빌더 패턴)

Builder Pattern

유용한 경우

1. 각각의 Part 로 이루어진 Object 생성시, 각 Part들의 생성들을 조합하여 Object의 생성을 가능하게하며, Part와 Object이 생성을 독립적으로 이룰 경우
2. 같은 종류의 Part들을 가지는 각각의 다른 Object 들을 동일한 방식으로 생성하고 싶을 때

장점

1. Builder 클래스는 Director클래스에게 객체를 생성할 수 있도록 인터페이스를 제공한다. 단, 생성 내부 방법은 숨긴다. Builder패턴에서 생성되는 객체의 내부구조가 바뀌더라도 기존 소스코드에 영향에 주지 않으며 새로운 하위 클래스를 생성하면 된다.
2. 객체를 생성하는 부분과 그것을 실제 표현하고 구성하는 부분을 분리 시켜줌으로써 서로간의 독립성을 기여할 수 있다.
3. 객체를 한꺼번에 생성하는 것이 아니라 부분부분 생성 후 최종 결과를 얻어가는 방식이므로 객체 생성과정을 상세히 지켜볼 수 있다.

단점

1. 객체 생성을 추가하는 것은 쉬우나 객체를 구성하는 각 부분들을 새롭게 추가하는 것은 어렵다.
2.  생성되는 객체의 구성들을 명확히 하여 추가하거나 수정해야하는 부분이 없어야 한다.

 게임 케릭터는 모두 머리, 몸, 팔, 다리, 꼬리 로 이루어져있으며, 몬스터 와 로봇 2가지 케릭터가 있는 경우. 게임 케릭터 생성을 관리하는 Director 가 있다. Director 생성시 몬스터 Builder를 이용하여 생성하면 Director는 몬스터가 생성되며, 로봇 Builder를 이용하여 만들어진 Director로 케릭터를 생성하면 로봇이 만들어진다. 위의 내용을 Code로 옮기면 아래와 같다.



#include "stdafx.h"
#include <iostream>
 
class CharacterDirector;
class Character;
class CharacterBuilder;
class RobotBuilder;
class MonsterBuilder;
 
// 캐릭터를 만드는 빌더
class CharacterBuilder {
public:
    virtual void makeCharacter() = 0;
    virtual void makeHead() = 0;
    virtual void makeBody() = 0;
    virtual void makeLegs() = 0;
    virtual void makeArms() = 0;
    virtual void makeTail() = 0;
    virtual Character* getResult() = 0;
};
 
// 캐릭터를 만들어줄 Director
class CharacterDirector {
public:
    CharacterBuilder* builder;
    CharacterDirector(CharacterBuilder* _builder):builder(_builder){}
    ~CharacterDirector(){
        if(builder)
        {
            delete builder;
            builder = NULL;
        }
    }
    Character* constructCharacter()
    {
        builder->makeCharacter();
        builder->makeHead();
        builder->makeBody();
        builder->makeArms();
        builder->makeLegs();
        builder->makeTail();
        return builder->getResult();
    }
};
 
// 캐릭터
class Character{
public:
    enum{
        robotHeadS = 0,     robotHeadM = 1,     robotHeadL = 2,
        robotBodyS = 3,     robotBodyM = 4,     robotBodyL = 5,
        robotLegsS = 6,     robotLegsM = 7,     robotLegsL = 8,
        robotArmsS = 9,     robotArmsM = 10,    robotArmsL = 11,
        robotTailS = 12,    robotTailM = 13,    robotTailL = 14,
        monsterHeadS = 15,  monsterHeadM = 16,  monsterHeadL = 17,
        monsterBodyS = 18,  monsterBodyM = 19,  monsterBodyL = 20,
        monsterLegsS = 21,  monsterLegsM = 22,  monsterLegsL = 23,
        monsterArmsS = 24,  monsterArmsM = 25,  monsterArmsL = 26,
        monsterTailS = 27,  monsterTailM = 28,  monsterTailL = 29,
    };
    int partHead;
    int partBody;
    int partLegs;
    int partArms;
    int partTail;
};
 
// 로봇 캐릭터를 만들어줄 빌더
class RobotBuilder : public CharacterBuilder{
public:
    Character* ch;
    Character* getResult(){return ch;}
    void makeCharacter(){ ch = new Character; }
    void makeHead(){ std::cout << "Make Robot Head\n"; }
    void makeBody(){ std::cout << "Make Robot Body\n"; }
    void makeLegs(){ std::cout << "Make Robot Legs\n"; }
    void makeArms(){ std::cout << "Make Robot Arms\n"; }
    void makeTail(){ std::cout << "Make Robot Tail\n"; }
};
 
// 몬스터 캐릭터를 만들어줄 빌더
class MonsterBuilder : public CharacterBuilder{
public:
    Character* ch;
    Character* getResult(){return ch;}
    void makeCharacter(){ ch = new Character; }
    void makeHead(){ std::cout << "Make Monster Head\n"; }
    void makeBody(){ std::cout << "Make Monster Body\n"; }
    void makeLegs(){ std::cout << "Make Monster Legs\n"; }
    void makeArms(){ std::cout << "Make Monster Arms\n"; }
    void makeTail(){ std::cout << "Make Monster Tail\n"; }
 
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    Character* monster;
    CharacterDirector* director = new CharacterDirector(new MonsterBuilder);
    monster = director->constructCharacter();
    delete director;
    director = NULL;
 
    Character* robot;
    director = new CharacterDirector(new RobotBuilder);
    robot = director->constructCharacter();
    delete director;
    director = NULL;
}




참조 : http://devsw.tistory.com

댓글 없음:

댓글 쓰기