Composite Pattern

917 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
917
On SlideShare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Composite Pattern

    1. 1. 컴포지트 패턴 (Composite Pattern)멀티플랫폼 지원관점에서... - MindHD 사례
    2. 2. 컴포지트 패턴컴포지트 패턴는 각각의 객체를 복합객체로 만든다.드로잉 객체를 복합하여 관리하기위해 컴포지트 패턴을 이용한다.이미지(돋보기, 포스트잇),텍스트 인스턴스를 조합할 수 있다.
    3. 3. 멀티플랫폼 이슈어떻게 멀티플랫폼(Win,Mac,iOS, WWW ... ) 을 지원할 것인가?
    4. 4. 컴포지트 패턴 메소드 호출 컴포지트 패턴의 메소드 호출은 복합객체에서 단말객체로 단방향 호출이 이루어진다. void Document::Draw(Painter* pPainter) {void View::OnDraw(CDC* pDC) graphics_->Draw(pPainter);{ } WinPainter aPainter(pDC); pDocument_->Draw(&aPainter);} void Picture::Draw(Painter* pPainter) { Iterator* iter = ... while(iter->HasObject()) iter->Draw(pPainter); } void Rect::Draw(Painter* pPainter) { // draw rect } void Text::Draw(Painter* pPainter) { // draw text }
    5. 5. 컴포지트 패턴 메소드 호출 컴포지트 패턴의 메소드 호출은 복합객체에서 단말객체로 단방향 호출이 이루어진다. void Document::Draw(Painter* pPainter) {void View::OnDraw(CDC* pDC) graphics_->Draw(pPainter);{ } WinPainter aPainter(pDC); pDocument_->Draw(&aPainter);} void Picture::Draw(Painter* pPainter) { Iterator* iter = ... while(iter->HasObject()) iter->Draw(pPainter); } void Rect::Draw(Painter* pPainter) { // draw rect } 멀티플랫폼 지원 void Text::Draw(Painter* pPainter) { // draw text }
    6. 6. 조건부 컴파일조건부 컴파일로 어느 정도 해결.지원 객체와 플랫폼이 늘어나면 관리 이슈 발생함.OOP적 해결방식은?
    7. 7. 플랫폼별 상속각 객체를 상속받은 Draw() 메소드에서 플랫폼별로 드로잉 작업을 수행한다. Rect Text WinRect WinText MacRect MacTextvoid MacRect::Draw(Painter* pPainter) { void WinRect::Draw(Painter* pPainter) CGContextRef context = pPainter->Context(); { CGContextAddRect(context, rect); CDC* pDC = pPainter->Context(); CGContextStrokePath(context); pDC->DrawRect(...);} }
    8. 8. 각 플랫폼별 상속 장단점플랫폼별 하위 클래스를 생성해야 한다.객체 또는 플랫폼이 늘어나는 경우 대처가 힘들다.파일 단위로 구분한 경우 파일 관리가 힘들 수 있다.파일 단위 구분은 작업 단위가 명확할 수 있는 장점.Abstract Factory 패턴과 연동.
    9. 9. 이터레이터 패턴 각 플랫폼별 뷰에서 개체를 순회하며 드로잉한다. Iterator class Iterator { public: Iterator(); virtual ~Iterator(); virtual const Glyph* Next() const = 0; virtual bool HasNext() const = 0; CompositeIterator };void View::OnDraw(CDC* pDC) - (void)drawRect:(CGRect)rect {{ CGContextRef context = UIGraphicsGetCurrentContext(); Iterator* iter = pDocument_->CreateIterator(); Iterator* iter = pDocument_->CreateIterator(); while(!iter->HasNext()) while(!iter->HasNext()) { { Rect* r = dynamic_cast<Rect*>((*iter)->Object()); Rect* r = dynamic_cast<Rect*>((*iter)->Object()); pDC->DrawRect(...); CGContextAddRect(context, r->Rect()); pDC->DrawText(...); DrawText(context,...); iter->Next(); iter->Next(); } }} }
    10. 10. 이터레이터 패턴단순 명확하다.(이터레이터 패턴 추가 제외)뷰는 컴포지트 패턴에 의존한다. 컴포지트 패턴 변경시 각 플랫폼별 뷰 (드로잉)을 변경해야 한다.뷰에서 하위 형변환이 발생한다.유연/확장성이 떨어질 수 있다. (드로잉 우선순위)
    11. 11. Strategy Pattern 스트레트지 패턴으로 각 플랫폼 코드를 캡슐화한다. void Document::Draw(Painter* pPainter) Painter { } graphics_->Draw(pPainter); void Picture::Draw(Painter* pPainter) { Iterator* iter = ...WinPainter MacPainter } while(iter->HasObject()) iter->Draw(pPainter); void Rect::Draw(Painter* pPainter) void View::OnDraw(CDC* pDC) { { pPainter->DrawRect(x_, y_, w_, h_); WinPainter aPainter(pDC); } pDocument_->Draw(&aPainter); } void Text::Draw(Painter* pPainter) { pPainter->DrawText(x_, y_, str_); }
    12. 12. Strategy Pattern 장단점.가장 명확하고 쉬운 해결책.컴포지트 패턴과 드로잉코드가 간접적으로 의존한다.확장/유연성이 비지터패턴에 비해 상대적으로 부족하다.결론적으로 브릿지패턴과 유사형태를 가진다.
    13. 13. 비지터 패턴 비지터 패턴을 이용하여 드로잉한다. void Rect::Draw(Painter* pPainter) { Painter } pPainter->Draw(this); void Text::Draw(Painter* pPainter) { pPainter->Draw(this); WinPainter MacPainter }void WinPainter::Draw(Rect* pRect) void MacPainter::Draw(Rect* pRect) {{ CGContextAddRect(context_, ...); pDC_->DrawRect(...); CGContextStrokePath(context_);} }void WinPainter::Draw(Text* pText) void MacPainter::Draw(Text* pText) {{ }} - (void)drawRect:(CGRect)rect { void OnDraw(CDC* pDC) CGContextRef context = { UIGraphicsGetCurrentContext(); WinPainter aPainter(pDC); MacPainter aPainter(context); pDocument->Draw(&aPainter); pDocument->Draw(&aPainter); } }
    14. 14. 비지터 패턴 비지터 패턴을 이용하여 드로잉한다. void Rect::Draw(Painter* pPainter) { Painter pPainter->Draw(this); } 이중 디스패치 void Text::Draw(Painter* pPainter) { pPainter->Draw(this); WinPainter MacPainter }void WinPainter::Draw(Rect* pRect) void MacPainter::Draw(Rect* pRect) {{ CGContextAddRect(context_, ...); pDC_->DrawRect(...); CGContextStrokePath(context_);} }void WinPainter::Draw(Text* pText) void MacPainter::Draw(Text* pText) {{ }} - (void)drawRect:(CGRect)rect { void OnDraw(CDC* pDC) CGContextRef context = { UIGraphicsGetCurrentContext(); WinPainter aPainter(pDC); MacPainter aPainter(context); pDocument->Draw(&aPainter); pDocument->Draw(&aPainter); } }
    15. 15. 비지터 패턴이해가 어렵다.컴포지트 순회 방식과 뷰의 의존도를 끊을 수 있다.컴포지트 패턴과 무관하게 추가 작업을 할 수 있다.(드로잉 우선순위 조절)하위 형변환을 직접적으로 하지 않는다.
    16. 16. 컴포지트 패턴컴포지트 패턴은 객체를 합성하여 동일한 메소드를 호출할 수 있는 매력적인 장점을 가진다.그러나, 상위 타입으로 객체를 저장하므로서 실행시점의 하위타입을 찾기 위한 어려운 문제점에 봉착한다.따라서,객체 합성의 개수 제한이 없고,객체 합성의 명확한 이점이 있을 경우에만 사용하는 것이 좋다.

    ×