디자인 패턴 101 - COMPOSITE

subutai·2021년 4월 13일
0

디자인 패턴 101

목록 보기
2/3
post-thumbnail

Composite

의도

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

풀어써본 의도

의도의 문장 자체는 어렵거나 이해가되지 않는 부분은 특별히 없으나
개념만을 설명하기 때문에 약간 잘 안 와닿는 부분이 있습니다.
우선, 개별 객체와 복합 객체라는 설명이 나옵니다.
복합객체란 여러 개별 객체를 가질 수 있는 객체인데요.
아래와 같은 예시로 보면 금방 이해할 수 있습니다.

윈도우의 파일시스템을 예시로 들어보겠습니다.
복합객체 는 폴더라고 생각할 수 있습니다.
단어 그대로 여러 단일 객체들이 복합되어서 포함될 수 있습니다
단일객체 는 파일이라고 생각할 수 있습니다.
파일을 눌렀을때는 그 파일이 실행될 뿐 다른 파일계층으로
들어가는 등의 연산은 존재하지 않죠

여기서 폴더는 파일은 제공해주지 않는 기능을 제공하는데요. 예를들면 드래그 앤 드롭이 있습니다.
다른 파일이나 폴더를 끌어다가 폴더 위에 떨어뜨리면 해당 폴더로 들어가게 되지만
파일 위에다가 떨어뜨리면 아무일도 일어나지 않죠

공통적으로 보면 폴더, 파일 모두 더블클릭, 우클릭등의 연산에 대한 반응을 제공합니다만
폴더는 자신이 가지고 있는 파일을 추가/조회/삭제 등 관리할 수 있는 기능을 가질 수 있습니다.
자식객체는 오직 자신이 제공할 수 있는 기능만을 제공하면 되겠죠. 눌렀을 때 exe 파일이라면 메모리에
파일을 올려두고 실행하거나, wav(미디어파일)이라면 기본 동영상 플레이어를 실행시켜서 재생을 하게됩니다.

이렇듯, 기본적인 기능(더블클릭, 우클릭) 이 있지만 복합객체는 이러한 기능을 제공하는것에 추가로
자식객체에 대한 관리 연산을 가져야 합니다.

특히, 부모객체와 자식객체가 동일하게 제공하는 연산, 여기서는 삭제가 가장 적절하겠는데요.

위와 같은 방식으로 복합객체는 단일객체와 동일한 인터페이스(삭제)를 갖지만
구체적인 구현방법(동작)은 다르게 됩니다.

활용성

1. 부분 - 전체의 객체 계통을 표현하고 싶을 때

조금 문장이 모호한데, 개인적인 해석으로는 클래스 상속구조를 통해서 계통화 되어있는 객체를
표현할 수 있다는 의미로 생각할 수 있습니다. 만약에 Composite 패턴을 사용하지 않고 이러한 트리구조를
생성한다면, 부모-자식 관계가 명확하게 표현이 되지 않습니다. 하지만 Composite 패턴을 사용하면
누가 부모-자식 관계를 클래스 타이핑으로 쉽게 표현할 수 있습니다

2. 객체를 일관되게 다루고자 할 때

사용자는, 복합 객체와 단일객체 사이의 차이를 알지못하더래도 동일한 인터페이를 사용해서 일을 시킬 수 있습니다.
삭제 연산의 경우, 파일(단일객체)은 자신만 삭제하면 끝이지만, 폴더(복합객체)는 자신은 물론이고
자신이 포함하고 있는 파일(단일객체) 또한 함께 삭제해주어야 합니다.
Composite 패턴으로 이러한 사항들을 구현해놓으면, 사용자는 파일/폴더를 분기문으로 구별하지 않고도
인터페이스에 노출되어 있는 '삭제' 연산을 호출하면 올바른 방식의 삭제 연산을 명령할 수 있습니다.

협력방법

복합구조 객체 간의 상호작용을 위해 Component 인터페이스를 사용합니다.
요청받은 대상이 Leaf면 자신이 정의한 행동(exe파일 열기, 동영상 재생 등)을 직접 수행합니다
만약에 대상이 Component 라면 자식 객체들에게 요청을 위임합니다(폴더에 속해있는 파일들에 삭제 명령)

장점

  1. 기본 객체와 복합 객체를 구분하지 않고 일관되게 프로그래밍할 수 있다.
  2. 코드가 단순해진다(복합객체인지 단일객체인지 구분하는 분기가 불필요)
  3. 새로운 종류의 구성요소를 쉽게 추가할 수 있따

단점

설계가 지나치게 범용성을 많이 가진다
-> 왜일까요? 앞에서 Component 인터페이스를 통해서 사용한다고 했는데요. 따라서 새로운 객체를 추가하는
연산인 Add(Component) 를 보면, 새로운 객체또한 Component 인터페이스를 가져야하므로 트리 내에서
컴포넌트를 특정 타입으로 제한하기가 어렵습니다. 물론, 제한할 수 있지만 런타임에서 타입체킹을 수행해줘야 합니다.

0개의 댓글