Thinking Different




 

 

 

Decorator 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
//------------------------------------------------------------------
// Component 인터페이스
class Component
{
public:
    virtual void operation() = 0;
};
 
//------------------------------------------------------------------
// ConcreteComponent 상속 클래스
class ConcreteComponent : public Component
{
public:
    void operation() { cout << "ConcreteComponent" << endl; }
};
 
//------------------------------------------------------------------
// Decorator 상속 클래스
class Decorator : public Component
{
public:
    Decorator(Component* c) : pComponent(c) {}
    ~Decorator() { if (pComponent) delete pComponent; }
 
public:
    void operation() { if (pComponent) pComponent->operation(); }
 
private:
    Component* pComponent;
};
 
//------------------------------------------------------------------
// ConcreteDecorator 상속 클래스
class ConcreteDecorator : public Decorator
{
public:
    ConcreteDecorator(Component* d) : Decorator(d) {}
 
public:
    void operation() { Decorator::operation(); cout << "ConcreteDecorator" << endl; }
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Component* pComponent = new ConcreteDecorator(new ConcreteDecorator(new ConcreteComponent()));
    pComponent->operation();
    delete pComponent;
 
    return 0;
}

 

 


 

 

예제를 통한 데코레이터 패턴(Decorator 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
76
77
78
79
#include <locale>
 
#if _UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif
 
//------------------------------------------------------------------
// Component 인터페이스
class ICoffeeComponent
{
public:
    virtual int GetCost() = 0;
    virtual tstring GetIngredients() = 0;
};
 
//------------------------------------------------------------------
// ConcreteComponent 상속 클래스
class Coffee : public ICoffeeComponent
{
public:
    int GetCost() { return 1000; }
    tstring GetIngredients() { return _T("커피"); }
};
 
//------------------------------------------------------------------
// Decorator 상속 클래스
class CoffeeDecorator : public ICoffeeComponent
{
public:
    CoffeeDecorator(ICoffeeComponent* c) : pComponent(c) {}
    ~CoffeeDecorator() { if (pComponent) delete pComponent; }
 
public:
    int GetCost() { if (pComponent) return pComponent->GetCost(); else return 0; }
    tstring GetIngredients() { if (pComponent) return pComponent->GetIngredients(); else return _T(""); }
 
private:
    ICoffeeComponent* pComponent;
};
 
//------------------------------------------------------------------
// ConcreteDecorator 상속 클래스
class MilkDecorator : public CoffeeDecorator
{
public:
    MilkDecorator(ICoffeeComponent* d) : CoffeeDecorator(d) {}
 
public:
    int GetCost() { return CoffeeDecorator::GetCost() + 200; }
    tstring GetIngredients() { return _T("우유 + ") + CoffeeDecorator::GetIngredients(); }
};
 
class WhipCreamDecorator : public CoffeeDecorator
{
public:
    WhipCreamDecorator(ICoffeeComponent* d) : CoffeeDecorator(d) {}
 
public:
    int GetCost() { return CoffeeDecorator::GetCost() + 500; }
    tstring GetIngredients() { return _T("휘핑크림 + ") + CoffeeDecorator::GetIngredients(); }
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    _wsetlocale(LC_ALL, L"korean");
 
    ICoffeeComponent* pComponent = new MilkDecorator(new WhipCreamDecorator(new CoffeeDecorator(new Coffee())));
    wcout << _T("비용 : ") << pComponent->GetCost() << endl;
    wcout << _T("재료 : ") << pComponent->GetIngredients().c_str() << endl;
    delete pComponent;
 
    getchar();
 
    return 0;
}


예제 결과

 

 

 

 

 

헤드 퍼스트 디자인 패턴:14가지 GoF 필살 패턴! - 프로그래밍 언어 | 쿠팡

쿠팡에서 헤드 퍼스트 디자인 패턴:14가지 GoF 필살 패턴! 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 프로그래밍 언어 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."