프로토타입 --------------------------------------------------------------------------------------------------
프로토타입 패턴은 하나의 원형객체를 두고 그 객체를 복사해서 새로운 객체를 생성하는 패턴을 말한다.
요약하자면
CPlayer* ProtoMonster = new Obj;
CPlayer* CreateMonster = ProtoMonster;
이런식으로 새롭게 생길 객체에 또하나의 객체를 대입하게 된다.
하지만 이렇게 할경우 주소값만 복사된 꼴이 되기 때문에 CreateMonster가 새로운 몬스터라고 할수는 없을 것이다.
새로운 방법이 필요하니 그에 대한 방법과 코드에 대한 방법을 보자.
아래의 코드와 패턴을 보면서 알아보도록 하자.
패턴 적용 스토리 -----------------------------------------------------------------------------------------------
당신은 몬스터를 생성하는 구조를 짜게 되었다. 하지만 몬스터가 등장하는 패턴을 보니 같은 몬스터가 여러개 등장하게 되어있다.
이제 플레이어를 만들어 보도록 하자.
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | #pragma once #include "stdafx.h" #include "include.h" enum MONSTER_TYPE { MONSTER_TYPE_0, MONSTER_TYPE_1, MONSTER_TYPE_2, MONSTER_TYPE_LAST }; typedef struct tagMonster { int At; int Dp; int Hp; int TextureIndex; void Setting(int iLevel) { At = (iLevel+1) * 10; Dp = (iLevel+1) * 10; Hp = (iLevel+1) * 10; TextureIndex = iLevel; } tagMonster(void) { At = 0; Dp = 0; Hp = 0; TextureIndex = 0; }; }MONSTERINFO, *PMONSTERINFO; class CMonster { private: MONSTERINFO tMonsterInfo; public: void SetMonsterInfo(MONSTERINFO& rInfo) { tMonsterInfo = rInfo; } public: CMonster* Clone(void) { switch(tMonsterInfo.TextureIndex) { case MONSTER_TYPE_0: cout << "CREATE MONSTER_TYPE_0" << endl; break; case MONSTER_TYPE_1: cout << "CREATE MONSTER_TYPE_1" << endl; break; case MONSTER_TYPE_2: cout << "CREATE MONSTER_TYPE_2" << endl; break; } return new CMonster(*this); } public: CMonster(void) {} ~CMonster(void) {} }; class CMonsterCreator { private: map<MONSTER_TYPE, CMonster*> m_MonsterProtoMap; public: void CreateProtoMonster(void) { for(int i = 0 ; i < MONSTER_TYPE_LAST ; ++i) { CMonster* pMonster= new CMonster; MONSTERINFO MonsterInfo; MonsterInfo.Setting(i); pMonster->SetMonsterInfo(MonsterInfo); m_MonsterProtoMap.insert(map<MONSTER_TYPE, CMonster*>::value_type((MONSTER_TYPE)i, pMonster)); } } public: CMonster* CreateFieldMonster(MONSTER_TYPE eMonsterType) { map<MONSTER_TYPE, CMonster*>::iterator FindIter = m_MonsterProtoMap.find(eMonsterType); if(FindIter == m_MonsterProtoMap.end()) return NULL; CMonster* pMonster = FindIter->second->Clone(); return pMonster; } public: CMonsterCreator(void) {} ~CMonsterCreator(void) {} }; #include "stdafx.h" #include "include.h" #include "Prototype.h" int _tmain(int argc, _TCHAR* argv[]) { CMonsterCreator MonsterCreate; MonsterCreate.CreateProtoMonster(); CMonster* pMonster; for(int i = 0; i < 10 ; ++i) { srand((unsigned)time(NULL)); int j = rand() % 3; Sleep(1000); pMonster = MonsterCreate.CreateFieldMonster( ( MONSTER_TYPE )( j ) ); } return 0; } |
보면 알겠지만 CreateProtoMonster()함수를 통해서 초반에 몬스터를 생성 해놓고
그 이후에 생성되는 것은 CreateFieldMonster()함수를 통해서 내부에 저장되어있는 몬스터의 값을 복제해서 새로운 객체를 생성한다.
하지만 이미 포인터로 만들어져 있기 때문에 단순 대입으로는 주소값대 주소값의 복사가 되어버리므로 리턴 형식을 자기자신의 새로운 형으로해서 자기 자신의 값을 채워넣어 복사하는
Clone함수를 사용해서 값을 새롭게 생성하여 복사해주면 된다.
'게임개발공부 > 디자인패턴' 카테고리의 다른 글
메인프레임 작업 01 (0) | 2013.12.21 |
---|---|
생성패턴 <싱글톤 패턴> (0) | 2013.12.18 |
쓰레드 환경에서 싱글톤? (0) | 2013.12.16 |
생성패턴 <팩토리 메서드> (0) | 2013.12.15 |
생성패턴 <빌더> (0) | 2013.11.24 |