상속으로 서브클래스를 만드는게 답이 없고 이를 조합으로 해결할 때 사용.
새로운 작업을 객체에 런타임에 연결 가능해짐.
그리고 ConcreateDecorator 클래스를 추가만해도 유지 보수가 가능해짐.
이때 통일성을 위해 Decorator, Component 는 모두 동일한 클래스의 상속이고
ConcreteComponent 와 ConcreateDocorator 는 위 도표처럼 그 아래에서 독립적으로 추가할 수 있음.
예제 코드
1 2 3 4 5 6 7 8 9 | // Component Class class VisualComponent { public: VisualComponent() = default; virtual void Draw() = 0; virtual void Resize() = 0; }; | cs |
1 2 3 4 5 6 7 8 9 | // Concrete Component class TextView : public VisualComponent { public: TextView() = default; virtual void Draw() { std::cout << "TextView"; } virtual void Resize() { std::cout << "TextView"; } }; | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | // Decorate Inteface class Decorator : public VisualComponent { public: Decorator(VisualComponent* c) : _component(c) {} virtual void Draw() { _component->Draw(); } virtual void Resize() { _component->Resize(); } private: VisualComponent* _component; }; | cs |
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 | // Concrete Decorator class BorderDecorator : public Decorator { public: BorderDecorator(VisualComponent* c, int borderWidth) : Decorator(c), _width(borderWidth) {} virtual void Draw() { Decorator::Draw(); DrawBorder(_width); } private: void DrawBorder(int width) { std::cout << " + Border"; } private: int _width; }; // Concreate Decorator class ScrollDecorator : public Decorator { public: ScrollDecorator(VisualComponent* c, int scrollWidth) : Decorator(c), _width(scrollWidth) {} virtual void Draw() { Decorator::Draw(); DrawScroll(_width); } private: void DrawScroll(int) { std::cout << " + Scroll"; } private: int _width; }; | cs |
1 2 3 4 5 | void main() { auto a = new ScrollDecorator(new BorderDecorator(new TextView(), 10), 3); a->Draw(); } | cs |
VisualComponent 는 모든 클래스에 공통으로 사용될 인터페이스임.
TextView 는 베이스가 되는 ConcreteComponent 임.
여기에 붙일 Decorator Interface 를 만들고, 이것을 상속하는 ScrollDecorator, BorderDecorator 를 만듬.
이를 위 main 처럼 사용하면 연쇄적인 실행이 일어나서 다음과 같은 결과를 줌.
추가 설명
장식자는 객체의 겉모양을 변경하고, 전략은 객체의 내부를 변경시키는 경쟁적 관계
댓글 없음:
댓글 쓰기