Thinking Different






Adapter Pattern - 아답터 패턴


  • 서로 다르게 구현된 인터페이스를 사용하고자 하는 다른 인터페이스로 변환한다.
  • 즉, A와 B의 인터페이스가 다를 경우 A에 맞추던가 B에 맞추던가 두개의 인터페이스를 통일시켜 사용하게 하는 구조이다
  • 서로 다르게 구현된 것을 하나의 패턴으로 일치시켜주는 것 뿐이다.
  • 아답터 패턴은 객체를 내부에 선언 사용하는 객체 아답터 패턴과 인터페이스를 상속받아 사용하는 클래스 아답터 패턴으로 나뉜다





샘플 코드)

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
//------------------------------------------------------------------
// Adaptee 클래스
class Adaptee
{
public:
    void adaptedOperation() { cout << "adaptedOperation()" << endl; }
};
 
//------------------------------------------------------------------
// Adapter 인터페이스
class Adapter
{
public:
    virtual void operation() = 0;
};
 
//------------------------------------------------------------------
// ConcreteAdapterA 상속 클래스 (객체 어뎁터 패턴, 객체 이용)
class ConcreteAdapterA : public Adapter
{
public:
    void operation() override { pAdaptee.adaptedOperation(); }
 
private:
    Adaptee pAdaptee; // 객체 사용
};
 
//------------------------------------------------------------------
// ConcreteAdapterB 상속 클래스 (클래스 어뎁터 패턴, 다중 상속 이용)
class ConcreteAdapterB : public Adapter, public Adaptee
{
public:
    void operation() override { adaptedOperation(); }
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    ConcreteAdapterA mObjectAdapter;
    mObjectAdapter.operation();
 
    ConcreteAdapterB mClassAdapter;
    mClassAdapter.operation();
 
    return 0;
}




예제를 통한 아답터 패턴(Adapter Pattern) 알아보기



예제) 문자열 숫자 변경 예제




<객체 어뎁터 패턴 구조>




<클래스 어뎁터 패턴 구조>



CStrData 클래스는 단순히 문자열로된 숫자를 저장하는 클래스입니다. 그런데 다른곳에서 사용되는 인터페이스는 문자열이 아닌 숫자(정수형)로만 사용 가능하다고 할 경우, 기존의 클래스를 변경하지 않고 아답터 클래스를 중간에 정의 한 후 그 내부에서 문자열로 된 데이터를 숫자로 단순히 변경만 시켜주는 구조입니다.



예제 코드)

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
#if _UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif
 
//------------------------------------------------------------------
// CStrData (숫자를 문자열로 저장하는 클래스)
class CStrData
{
public:
    CStrData(const TCHAR* data) : m_strData(data) {}
    const TCHAR* GetStringData() const { return m_strData.c_str(); }
 
private:
    tstring m_strData;
};
 
//------------------------------------------------------------------
// Adapter 인터페이스 정의
class Adapter
{
public:
    virtual int operation() = 0;
};
 
//------------------------------------------------------------------
// ConcreteAdapterA 클래스 (객체 어뎁터 패턴)
class ConcreteAdapterA : public Adapter
{
public:
    ConcreteAdapterA(const TCHAR* data) : mStrData(data) {}
    int operation() override { return _ttoi( mStrData.GetStringData() ); }
 
private:
    CStrData mStrData;    // 객체 내부 선언 사용
};
 
//------------------------------------------------------------------
// ConcreteAdapterB 클래스 (클래스 어뎁터 패턴)
class ConcreteAdapterB : public Adapter, public CStrData
{
public:
    ConcreteAdapterB(const TCHAR* data) : CStrData(data) {}
    int operation() override { return _ttoi( GetStringData() ); }
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    ConcreteAdapterA mObjectAdapter(_T("12345"));
    ConcreteAdapterB mClassAdapter(_T("54321"));
 
    int iData1 = mObjectAdapter.operation();
    int iData2 = mClassAdapter.operation();
 
    cout << iData1 << endl;
    cout << iData2 << endl;
 
    return 0;
}


예제 결과)