2016년 2월 26일 금요일

GoF의 디자인 패턴 - Composite

Structural Patterns(구조 패턴) :: Composite(복합체)

구분
 객체 구조 (Object Structural)

의도
 - 부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성한다. 사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴이다.

포인트
 - 기본 클래스와 이들의 컨테이너를 모두 표현할 수 있는 하나의 추상화 클래스를 정의하는 것

사용시기
 - 부분-전체의 객체 계통을 표현하고 싶을 때
 - 사용자가 객체의 합성으로 생긴 복합 객체와 개객의 객체 사이의 차이를 알지 않고도 자기 일을 할 수 있도록 만들고 싶을 때, 사용자는 복합 구조(Composite Structure)의 모든 객체를 똑같이 취급하게 된다.

장점과 단점
 - 기본 객체와 복합 객체로 구성된 하나의 일관된 클래스 계통을 정의한다. 기본 객체는 더 복합적인 객체들에 속해 있을 수 있다. 물론 이 복합 객체 역시 다른 것에 속해 있는 것일 수 있다. 그러나 사용자 코드는 일반화된 상위 개념의 객체를 조작하는 방식으로 프로그래밍하면, 런타임 기본 객체와 복합 객체를 구분하지 않고 일관되게 프로그래밍할 수 있게 된다.
 - 사용자의 코드가 단순해진다. 사용자 코드는 복합 구조이나 단일 객체와 동일하게 다루는 코드로 작성되기 때문이다. 즉, 사용자는 객체의 특성이 복합 구조인지 단일 구조인지조차 모르고 개발할 수 있다. 이런 구분이 필요치 않으므로 개발자의 코드에 "꼬리표-case-문장" 스타일의 함수를 쓸 필요가 없어지므로 코드가 단순해진다.

 - 새로운 종류의 구성요소를 쉽게 추가할 수 있다. 새롭게 정의된 Composite나 Leaf의 서브클래스들은 기존에 존재하는 구조들과 독립적으로 동작이 가능하게 된다. 그러므로 새로운 요소가 추가되었다고 해서 사용자의 프로그램이 변경될 필요는 전혀 없다.

 - 설계가 지나치게 범용성을 많이 가진다. 새로운 요소를 쉽게 추가할 때의 단점은 복합체의 구성요소에 제약을 가하기 힘들다는 것이다. 가끔 복합체가 오직 한 개의 구성요소만 가졌으면 할 때가 있다. Composite클래스만으로 타입 시스템을 통해 이런 제약을 가할 수 없다. 런타임 점검이 들어가야 한다.

구현의 유의점
 1. 포함 객체에 대한 명확한 참조자
 2. 구성요소 공유
 3. Component 인터페이스를 최대화
 4. 자식을 관리하는 연산 선언
 5. 컴포넌트가 컴포넌트의 리스트를 구현할 수 있을까?
 6. 자식 사이의 순서 정하기
 7. 성능 개선을 위한 캐싱(Caching)
 8. 누가 구성요소를 삭제하는 책임을 질까?
 9. 구성요소를 저장하기 위해 가장 적당한 데이터 구조는?

관련 패턴
 구성요소-부모 간의 연결은 책임 연쇄 패턴에서 많이 사용되는 예이다.
 장식자 패턴은 자주 복합체 패턴과 함께 사용된다. 이 두 패턴이 함께 사용될 때는 둘 다 동일한 하나의 부모 클래스를 상속받게 된다, 따라서 장식자는 Add(), Remove(), GetChild()와 같은 연산을 통해서 Component의 인터페이스를 지원해야 한다.
 플라이급 패턴으로 구성요소의 공유 방법을 얻을 수 있다. 단, 공유되는 구성요소의 보무는 참조할 수 없다.
 반복자 패턴을 이용하면, 구성요소를 순회하는 방법을 얻을 수 있다.
 방문자 패턴을 이용하면, 이 패턴을 사용하지 않을 때 Composite와 Leaf클래스에 걸쳐 분산될 수 있는 행동을 국소화시킬 수 있다.


참조문헌
- GoF의 디자인패턴

댓글 없음:

댓글 쓰기