브릿지패턴 --------------------------------------------------------------------------------------------------

객체란 선언과 구현으로 나뉜다.

선언이란 외부에 공개되는 인터페이스(함수나 맴버들)을 의미하며.

구현이란 인터페이스의 실제적인 동작을 정의해 놓고 있다.

하지만 하나의 구현파일안에 조건에 따른 다른 내용으로 분류되거나 하는 일이 있을수 있다.

하나의 클래스가 어떠한 일을 하는데 조건문에 따른 코드가 너무 길어져서 가독성이 떨어지고 처리해야할 코드가 길어진다면 어떻게 해야할까?

혹은 몇개의 함수만 다른 동작을 하고 나머지는 완전히 똑같은 동작을 하는 클래스가 여러개 있을때.

이들을 어떻게 하면 효율적으로 모으고 관리할 수 있을까?

그에 대한 새로운 방식을 지원해주는 것이 브릿지 패턴이라고 할 수 있다.


패턴적용 스토리 -----------------------------------------------------------------------------------------------

당신은 몬스터의 인공지능을 맡게 되었다. 

그런데 완전히 같은 몬스터라도 인공지능이 다르게 구현될 수 있다고 한다.

즉 같은 몬스터 A라도

소심한 몬스터A

대담한 몬스터A

비열한 몬스터A

같은 식으로 구현이 될 수 있다는 이야기 이다.

그럼 그것을 효율적으로 해결하기 위한 방법을 보자.


uml -----------------------------------------------------------------------------------------------


몬스터 클래스는 내부에 브릿지를 가지고 있다. 이 브릿지는 몬스터의 AI를 담당한다.

몬스터 AI를 담당하는 브릿지가 있기 때문에 몬스터 클래스 내부에서는 실제적인 AI의 동작을

몬스터끼리 달라져야할 부분만 구성하고 다른 부분은 몬스터 내부의 메소드에서 처리하면 된다.

즉 인터페이스의 구현을 연결된 브릿지에 맡김으로 해서 한 클래스에 코드과중이나 역할을 분산시킬 수 있다.



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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#pragma once
 
#include "stdafx.h"
#include "include.h"
 
enum MONSTER_AI
{
    MONSTER_AI_WILD,
    MONSTER_AI_CHICKEN,
    MONSTER_AI_BASTARD
};
 
typedef struct tagMonsterInfo
{
    MONSTER_AI    iAiPatton;
    int            iAtt;
 
    tagMonsterInfo(void) {}
    tagMonsterInfo(const MONSTER_AI& _iAiPatton, const int& _iAtt)
    {
        iAiPatton = _iAiPatton;
        iAtt = _iAtt;
    }
 
}MONSTERINFO, *PMONSTERINFO;
 
class CMonsterAiBridge
{
public:
    virtual void AiAction(const MONSTERINFO& _MonsterInfo) const = 0;
 
public:
    CMonsterAiBridge(void) {}
    virtual ~CMonsterAiBridge(void) {}
};
 
class CWildMonsterAi
    : public CMonsterAiBridge
{
public:
    virtual void AiAction(const MONSTERINFO& _MonsterInfo) const
    {
        cout << "************* 사나운 몬스터AI *************" << endl;
        cout << "사나우니까 공격!" << _MonsterInfo.iAtt << "피해를 입혔다" << endl;
        cout << "사나우니까 공격!" << _MonsterInfo.iAtt << "피해를 입혔다" << endl;
        cout << "사나우니까 공격!" << _MonsterInfo.iAtt << "피해를 입혔다" << endl;
        cout << endl;
    }
 
public:
    CWildMonsterAi(void) {}
    virtual ~CWildMonsterAi(void) {}
};
 
class CChickenMonsterAi
    : public CMonsterAiBridge
{
public:
    virtual void AiAction(const MONSTERINFO& _MonsterInfo) const
    {
        cout << "************* 겁쟁이 몬스터AI *************" << endl;
        cout << "플레이어와 거리가 가깝다! 도망!" << endl;
        cout << "플레이어와 거리가 가깝다! 도망!" << endl;
        cout << "거리가 벌어졌으니 활들고 공격!" << _MonsterInfo.iAtt << "피해를 입혔다" << endl;
        cout << endl;
    }
 
public:
    CChickenMonsterAi(void) {}
    virtual ~CChickenMonsterAi(void) {}
};
 
class CBastardMonsterAi
    : public CMonsterAiBridge
{
public:
    virtual void AiAction(const MONSTERINFO& _MonsterInfo) const
    {
        cout << "************* 비열한 몬스터AI *************" << endl;
        cout << "항복! 뿌잉뿌잉" << endl;
        cout << "플레이어가 전투태세를 풀었다!" << endl;
        cout << "방심하고 있으니 공격!" << _MonsterInfo.iAtt << "피해를 입혔다" << endl;
        cout << "플레이어가 공격하려고 한다!!" << endl;
        cout << "항복! 뿌잉뿌잉" << endl;
        cout << "플레이어가 전투태세를 풀었다!" << endl;
        cout << "방심하고 있으니 공격!" << _MonsterInfo.iAtt << "피해를 입혔다" << endl;
        cout << endl;
    }
 
public:
    CBastardMonsterAi(void) {}
    virtual ~CBastardMonsterAi(void) {}
};
 
class CMonster
{
private:
    MONSTERINFO          m_MonsterInfo;
    CMonsterAiBridge* m_MonsterAiBridge;
 
public:
    void InitMonster(void)
    { 
        switch(m_MonsterInfo.iAiPatton)
        {
        case MONSTER_AI_WILD:
            m_MonsterAiBridge = new CWildMonsterAi();
            break;
        case MONSTER_AI_CHICKEN:
            m_MonsterAiBridge = new CChickenMonsterAi();
            break;
        case MONSTER_AI_BASTARD:
            m_MonsterAiBridge = new CBastardMonsterAi();
            break;
        }
    }
 
    void AiAction(void)
    {
        m_MonsterAiBridge->AiAction(m_MonsterInfo);
    }
 
public:
    CMonster(void) {}
    CMonster(const MONSTERINFO& _MonsterInfo) 
    {
        m_MonsterInfo = _MonsterInfo;
    }
    ~CMonster(void
    {
        SAFE_DELETE(m_MonsterAiBridge);
    }
};
 
// Bridge.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
 
#include "stdafx.h"
#include "Bridge.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
#ifdef _DEBUG
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
 
    CMonster* MonsterWild = new CMonster(MONSTERINFO(MONSTER_AI_WILD, 15));
    CMonster* MonsterChicken = new CMonster(MONSTERINFO(MONSTER_AI_CHICKEN, 15));
    CMonster* MonsterBastard = new CMonster(MONSTERINFO(MONSTER_AI_BASTARD, 15));
 
    MonsterWild->InitMonster();
    MonsterChicken->InitMonster();
    MonsterBastard->InitMonster();
 
    MonsterWild->AiAction();
    MonsterChicken->AiAction();
    MonsterBastard->AiAction();
 
    SAFE_DELETE(MonsterWild);
    SAFE_DELETE(MonsterChicken);
    SAFE_DELETE(MonsterBastard);
 
    return 0;
}






Posted by JJOREG