본문 바로가기

Develop/DESIGN PATTERNS

[GoF Design Pattern] 컴포짓 패턴 (Composite pattern)

1. 컴포짓 패턴이란?

클라이언트가 전체 계층 구조와, 계층 구조를 구성하는 부분적인 계층 구조를 동일하게 취급할 수 있는 패턴이다.

따라서 클라이언트는 사용하고자 하는 컴포넌트가 어떤 위치에 있는지 상관하지 않고 동일한 인터페이스를 적용할 수 있다.

 

트리 구조를 활용하기 때문에 당연히 트리를 만들어야 한다는 특징이 있다.

또한 컴포짓 패턴을 잘 활용하면 보다 객체지향적인 코드를 작성할 수도 있다.

2. 구현 방법

다음과 같은 구조를 가져갈 수 있다.

 

보시다시피 클라이언트는 트리 구조로 이루어진 컴포넌트를 사용하고 있다.

이때 트리 구조에 속한 컴포넌트 모두를 Component 인터페이스로 받을 수 있다. 그렇기 때문에 동일하게 사용 가능하다.

 

만약 컴포짓 패턴을 구현하지 않고 Bag에 들어있는 Item 가격의 합을 구하려면 클라이언트가 너무 많은 부분을 알아야 한다.

bag.getItems().stream().mapToInt(Item::getPrice).sum();

이건 객체지향스러운 코드라고 할 수 없다.

private void getPrice(Component component) {
  return component.getPrice();
}

이때 컴포짓 패턴을 활용한다면 다음과 같이 작성이 가능하다.

가격 합을 구하고자 하는 컴포넌트가 계층 구조에서 어떤 위치에 있는지 신경 쓰지 않아도 된다.

3. 장/단점

1) 장점

먼저 복잡한 트리 구조를 편리하게 사용할 수 있다!

또한 클라이언트 코드를 변경하지 않고 새로운 Leaf, Composite를 추가할 수 있다. (OCP)

2) 단점

공통된 인터페이스를 정의하기 위해 억지로 트리 구조를 만들어야 할 수도 있다. (지나친 일반화)

이때 억지로 타입체킹을 해야 하는 경우가 생기기도 한다.

따라서 이런 경우는 디자인 패턴에 너무 종속적으로 코드를 작성하고 있는 게 아닌지에 대한 검토가 필요하다.