본문 바로가기

Design Patterns/영문 위키(Wikipedia)

Composite Pattern (콤포짓 패턴)

먼저 이 글은 영문위키의 글을 번역한 글임을 알려드립니다.

영어 실력이 부족한 관계로 오역이 있을 수도 있습니다.

원문 주소 : http://en.wikipedia.org/wiki/Composite_pattern



구조적 패턴 - 콤포짓 패턴



소프트웨어 공학에서 콤포짓 패턴은 분할하는(partitioning) 디자인 패턴이다. (왜 partitioning이라는 단어가 나왔는지 잘 이해가 안되네요.;;) 콤포짓 패턴은 객체 그룹이 단일 객체와 같이 취급되도록 한다. 컴포짓의 목적(의도, intent)은 객체들을 트리(tree) 구조로 "구성(compose)"하여 부분-전체 구조(part-whole hierarchies)를 표현하기 위함이다. 콤포짓 패턴을 구현하는 것은 단일 객체(individual objects)와 구성(composition, 여기에서는 그룹 정도로 이해해도 괜찮을 것 같네요.)을 동일하게 취급하도록 해준다.

동기 Motivation

트리 구조의 데이터를 다룰 때, 프로그래머는 종종 리프노드(leaf-node)와 브랜치(branch)를 구분해야만 한다. 이는 코드를 더욱 복잡하게 만들고 따라서 에러가 발생하기도 쉽다. 해결책은 복합객체(complex)와 원시객체(primitive)를 동일하게 다루는 인터페이스를 사용하는 것이다. 객체 지향 프로그래밍에서 컴포짓은 하나 이상의 비슷한 객체들을 가지고 하나의 구성(composition)으로 설계된 객체이다. 이는 객체 사이의 "has-a"관계로 알려져있다. 중요한 컨셉은 객체의 한 인스턴스를 다룰 때, 그 객체들의 그룹을 다루는 것처럼 다룰 수 있다는 것이다. 모든 컴포짓 객체들에서 당신이 수행할 수 있는 동작들(operations)은 종종 최소 공통 분모(least common denominator) 관계에 있다. 예를 들어, 그룹핑된(grouped) 도형(shapes)들을 화면에 그리는 시스템을 정의한다고 하면, 도형들의 그룹을 리사이징(resizing)하는 것이 하나의 도형을 리사이징하는 것과 같은 효과를 가지도록 정의하는 것이 유용할 것이다. 

언제사용하는가? When to use

컴포짓은 클라이언트 프로그램이 객체들의 구성(composition)과 개개의 객체 사이에 차이점을 무시해야할 때 사용될 수 있다. 만약 프로그래머가 여러개의 객체들을 같은 방법으로 사용하거나, 종종 그 객체 각각을 다루기 위해 거의 비슷한 코드를 사용하고 있는 자신의 모습을 발견한다면, 컴포짓이 좋은 선택이 될 수 있다. ; 이러한 상황에서 원시(primitive)객체와 구성 객체를 동일하게 다루는 것이 덜 복잡하다. 

구조 Structure

Component

  • 컴포넌트 자신을 포함한 모든 컴포넌트에 대한 추상화이다.
  • 구성(composition)에 있는 객체들의 인터페이스를 정의한다.
  • (선택적으로) component의 부모에 대한 접근하기 위한 재귀적인 구조(recursive structure)의 인터페이스를 정의하고, 적절하다면 구현한다.

Leaf

  • 구성(composition)에 있는 leaf 객체들을 표현한다.
  • component의 모든 메서드를 구현한다.

Composite

  • composite 컴포넌트를 표현한다.(자식들을 가지는 컴포넌트)
  • 자식들을 다루기 위한 메서드를 구현한다.
  • 모든 component 메서드를 구현한다.(일반적으로 메서드 기능을 자식에게 위임해서 구현한다. 여기에서 위임이라함은 자식의 기능을 호출한다고 보면 될 것 같네요.)

변형 Variation

Design Patterns에 묘사되어 있듯이,  이 패턴에는 Composite 클래스 뿐만 아니라 메인 Component 인터페이스에도 자식을 관리하는 메서드를 포함하고 있다. 더 최근의 몇몇 설명에서는 이러한 메서드를 누락시키고 있다. 

예 Example

자바로 작성된 다음의 예제는 Graphic 클래스를 구현하는데, 이 클래스는 Ellipse(타원)이나 다른 몇몇 그래픽의 구성(composition)이 될 수 있다. 모든 그래픽은 출력될 수 있다.


수학적으로 표현하면 다음과 같다.

Graphic = ellipse | GraphicList
GraphicList = empty | Graphic GraphicList


이는 직사각형과 같은 다른 도형들과 translate와 같은 다른 메서드들을 구현하게 끔 확장될 수도 있다.