Thinking Different






Bridge Pattern - 브리지 패턴


  • 구현부에서 추상층을 분리하여 각자 독립적으로 변형할 수 있게 하는 패턴이다.
  • 즉, 기능과 구현을 별도의 클래스로 정의해서 서로를 분리하는 방법이다
  • 전형적인 상속을 이용한 패턴으로 확장 설계에 용이하다







샘플코드)

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
//------------------------------------------------------------------
// Implementor 인터페이스
class Implementor
{
public:
    virtual void operationImpl() = 0;
};
 
//------------------------------------------------------------------
// ConcreteImplementorA 상속 클래스
class ConcreteImplementorA : public Implementor
{
public:
    void operationImpl() { cout << "ConcreteImplementorA" << endl; }
};
 
//------------------------------------------------------------------
// ConcreteImplementorB 상속 클래스
class ConcreteImplementorB : public Implementor
{
public:
    void operationImpl() { cout << "ConcreteImplementorB" << endl; }
};
 
//------------------------------------------------------------------
// Abstraction 인터페이스
class Abstraction
{
public:
    virtual void operation() = 0;
};
 
//------------------------------------------------------------------
// ConcreteAbstraction 상속 클래스
class ConcreteAbstraction : public Abstraction
{
public:
    ConcreteAbstraction(Implementor* i) : impl(i) {}
 
public:
    void operation() { impl->operationImpl(); }
 
private:
    Implementor* impl;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    ConcreteImplementorA pConcreteImplementorA;
    ConcreteImplementorB pConcreteImplementorB;
 
    ConcreteAbstraction mConcreteAbstractionA(&pConcreteImplementorA);
    ConcreteAbstraction mConcreteAbstractionB(&pConcreteImplementorB);
 
    mConcreteAbstractionA.operation();
    mConcreteAbstractionB.operation();
 
    return 0;
}




예제를 통한 브리지 패턴(Bridge Pattern) 알아보기



예제) 스타크래프트 유닛과 무기 사용 인터페이스 예제


각각 무기와 유닛 인터페이스를 정의하고 하위 클래스에서 구현하였습니다. 각각의 유닛들은 무기를 사용할 수 있도록 브리지 패턴을 이용하여 구현하였다.


예제 코드)

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
//------------------------------------------------------------------
// Weapon 인터페이스
class 무기
{
public:
    virtual void 사용() = 0;
};
 
//------------------------------------------------------------------
// ConcreteImplementorA 상속 클래스
class 파이어건 : public 무기
{
public:
    void 사용() { cout << "화염방사기 사용" << endl; }
};
 
//------------------------------------------------------------------
// ConcreteImplementorB 상속 클래스
class 총 : public 무기
{
public:
    void 사용() { cout << "총 사용" << endl; }
};
 
//------------------------------------------------------------------
// Abstraction 인터페이스
class 유닛
{
public:
    virtual void 사용() = 0;
};
 
//------------------------------------------------------------------
// ConcreteAbstraction 상속 클래스
class 마린 : public 유닛
{
public:
    마린(무기* i) : mWeapon(i) {}
 
public:
    void 사용() { cout << "마린 ";  mWeapon->사용(); }
 
private:
    무기* mWeapon;
};
 
//------------------------------------------------------------------
// ConcreteAbstraction 상속 클래스
class 파이어벳 : public 유닛
{
public:
    파이어벳(무기* i) : mWeapon(i) {}
 
public:
    void 사용() { cout << "파이어벳 "; mWeapon->사용(); }
 
private:
    무기* mWeapon;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    총 mGun;
    파이어건 mFireGun;
 
    마린 mMarin(&mGun);
    파이어벳 mFirebet(&mFireGun);
 
    mMarin.사용();
    mFirebet.사용();
 
    return 0;
}


예제 결과)


댓글 6

  • ㅇㅈㄴ (2017.12.31 12:09 신고)

    예제가 둘 다 잘못된것 같습니다.

    기능과 구현을 별도의 클래스로 분리하라는 설명은 맞지만 예제는 구현만 있고 기능 클래스가 보이지 않습니다.

    • Favicon of http://copynull.tistory.com BlogIcon copynull (2017.12.31 17:31 신고)

      문제제기 하신 부분에 대한 답변 드립니다.
      예제에 의해 설명드리면 '유닛' 클래스는 기능(추상) 클래스이고, '무기' 클래스는 구현 클래스 입니다. 즉 기능 클래스가 구현 클래스를 포함하는 구조를 통한 구성관계(Bridge)에 있는 패턴입니다.

      도움이 되셨으면 좋겠습니다.
      혹시 제가 잘못 이해하고 있는 점이 있다면 답변 부탁드립니다.
      감사합니다.

  • ㅇㅈㄴ (2018.01.02 13:07 신고)

    기능 클래스는 abstract class이고, 구현 클래스는 interface를 상속받습니다.

    브리지 패턴은 구현 클래스와 기능 클래스를 연결하는 패턴입니다.

    무기와 유닛 클래스는 둘다 구현 클래스입니다.

    • Favicon of http://copynull.tistory.com BlogIcon copynull (2018.01.02 19:25 신고)

      해당 클래스 예제에 대한 부분은 wiki 백과의 내용을 참고하였습니다.
      아래 링크를 통해 확인하시기 바라며 추가 설명될 부분은 생략하도록 하겠습니다.

      https://ko.wikipedia.org/wiki/%EB%B8%8C%EB%A6%AC%EC%A7%80_%ED%8C%A8%ED%84%B4

      다른 참고할만한 bridge pattern 사이트 하나 더 알려드립니다.
      http://ikeptwalking.com/bridge-design-pattern-explained/

      답변이 이루어지지 않는다면 코드를 하나 예를 들어서 답변 부탁드립니다.
      감사합니다.

    • ㅇㅈㄴ (2018.01.09 15:14 신고)

      기능 클래스는 기존 클래스에 새로운 기능을 추가한 클래스이고 구현 클래스는 순수 가상함수를 상속 받아 구현을 한 클래스라고 알고 있습니다. (Java 언어로 배우는 디자인패턴 입문 참조)

      두 클래스는 순수 가상함수를 구현하는 구현 클래스로 보입니다. 제가 틀렸을수도 있으니 확인후 답변 부탁드립니다.

      더불어, 기능 클래스와 구현 클래스의 차이점을 설명해 주셨으면 좋겠습니다.

    • Favicon of http://copynull.tistory.com BlogIcon copynull (2018.01.09 21:33 신고)

      위 댓글 답변으로 설명을 드렸지만 예제 코드에서 보시면 '유닛 클래스는 기능 클래스이고, '무기' 클래스는 구현 클래스 입니다.
      자바코드에서 보자면 구현 클래스는 interface 를 쓸겁니다. 기능 클래스는 abstract 를 씁니다. 하지만 c 코드에서는 정의하는 인자가 별도로 존재하지 않지요, 모두 class로 작성하고 순수가상함수로 처리합니다. 물론 기능 클래스는 다른 기능 함수들을 추가할 수 있지만 저는 한가지 예로써 '사용()' 이라는 함수만 예를 들었습니다. 또한 구현클래스와 기능 클래스도 하위 클래스로 확장이 가능합니다.
      자바에서 보는 코드로 c코드를 이해하기에는 어려운 점이 있긴 합니다.
      브리지 패턴을 보면 일단 기능 클래스에 구현(인터페이스)클래스를 포함하게 되는 구조가 됩니다. 클래스 다이어그램을 보시면 바로 이해되실건데요. 맨위에 그림입니다.

Prev 1 ··· 176 177 178 179 180 181 182 183 184 ··· 283 Next