본문 바로가기

진리는어디에

Composite Pattern

의도
 '전체 부분'을 표현하기 위해 객체들을 트리구조로 묶을 수 있다. 클라이언트 코드는 각 개별적인 객체(부분)와 다른 객체를 포함하는 객체(전체)를 동일한 인터페이스를 통해 사용할 수 있다.

구조

사용자 삽입 이미지


 위의 모델에서 Composite 클래스는 Component 인터페이스를 포함하는 형식으로, 실제적으로 Component 인터페이스에는 Leaf나 Composite의 인스턴스를 가리키게 된다. 이런 구조를 인스턴스 다이어그램으로 표현 하면 아래와 같다.
사용자 삽입 이미지

 하나의 집합객체(Composite)가 Leaf나 Composite를 포함하고 그것은 재귀적으로 계속 이어진다. 모든 인스턴스들은 Component 인터페이스를 구현하고 있기 때문에 클라이언트에서는 Leaf와 Composite에 구분없이 동일하게 취급이 가능하게 된다.

역할 
 *  Component
  - Leaf와 Composite를 동일하게 취급하기 위한 인터페이스 정의
  - 전체 클래스에 속한 요소들을 관리하는데 필요한 인터페이스 정의
  - 순환(recursive) 구조에서 요소들을 포함하는 전체 클래스로의 접근에 필요한 인터페이스를 정의 한다.
 * Leaf
  - ‘내용물을 나타내는 역할, 이 안에는 다른 내용물을 넣을 수 는 없다. 파일 디렉토리 관계에서 보면 파일에 해당한다.
 * Composite
  - '집합체' 역할, 이 안에는 내용물과 다른 집합체가 포함될 수 있다. 파일과 디렉토리 관계에서 디렉토리에 해당한다.
 *
 Client의 역할
  - Composite 패턴의 이용자.

구현 관련 신경 쓸 사항
 1. 부모에 대한 참조자를 유지하면 구조를 거슬러 올라가거나 요소를 삭제 하는 과정을 좀 더 쉽게 만든다.
 2. Component의 인터페이스를 최대화 한다. 하지만 Leaf에는 필요 없는 오퍼레이션이 인터페이스에 정의 되어 구조를 파악하는데 방해가 될 수 있다. 그럼에도 불구하고 Leaf와 Composit에 상관 없이 동일한 처리를 하기 위해서 인터페이스에 최대한 많은 오퍼레이션을 정의 한다.
 3. 성능 개선을 위한 캐싱. 자식들에 대한 정보의 일부를 부모가 캐싱하고 있으므로써 자식노드 까지 탐색할 필요 성을 줄여 준다. 하지만 해당 연산 작업이 집중적으로 수행되고 기본데이터가 변경되지 않는다는 것을 확신 할 수 없을 경우 이러한 기능이 필요 없을 수도 있다.
 
결론
 Composite 패턴은 단순 객체 및 복잡한 객체의 계층 구조에 대한 클래스를 정리할 수 있게 하여 클라이언트의 프로그램에서는 모두 같은 종류로 나타낸다. 노드와 리프가 같은 방식으로 관리되기 때문에 이렇게 단순화해서 클라이언트도 그것에 맞추어 간단해질 수 있다.

 Composite 패턴은 개발자의 컬렉션에 새로운 컴포넌트를 추가하기가 매우 쉬운데, 해당 패턴이 유사한 프로그램밍 인터페이스를 지원하는 한 이것은 계속 유효하다. 반면에 Composite 패턴은 시스템을 지나치게 일반화한다는 단점이 있다. 이런 단점이 일반적으로 바람직하게 용인되는 경우 아마도 특정 클래스를 제한할 때 어려움을 겪게 될 것 이다.

Ref.
 Composite 패턴 정리 : http://blog.naver.com/smurpettt?Redirect=Log&logNo=150000478576
 Composite Message 패턴 : http://blog.naver.com/only2u4u?Redirect=Log&logNo=120042169519
 GoF Design Patterns
 Java 언어로 배우는 디자인 패턴 입문
 Headfirst Design pattern

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!