노트

컴포지트 패턴

Composite

설계#pattern · 연결된 개념 5개

쉽게 말하면

컴포지트 패턴은 '이 상자 무게가 얼마야?'라고 물으면 상자가 안에 든 물건과 작은 상자들에게 다시 물어 더해 오는 방식이에요. 물건 하나든 상자째든 똑같이 물어볼 수 있죠.

비유가 깨지는 곳 현실 상자와 달리 코드에서는 모두 같은 인터페이스를 따르다 보니, 잎에 쓸모없는 addChild() 같은 메서드가 생기기 쉬워요. 공통 연산만 인터페이스에 두고 자식 관리는 가지에만 둬요.

개별 객체(잎, Leaf)와 객체들의 묶음(가지, Composite)을 같은 인터페이스로 다뤄, 트리 구조를 재귀적으로 처리하는 패턴.

interface FsNode { size(): number }
 
class FileNode implements FsNode {
  constructor(private bytes: number) {}
  size() { return this.bytes }
}
class FolderNode implements FsNode {
  constructor(private children: FsNode[]) {}
  size() { return this.children.reduce((sum, c) => sum + c.size(), 0) }
}
  • 호출자는 파일인지 폴더인지 신경 쓰지 않고 size()만 부른다. 트리 순회 로직이 각 노드 안에 들어간다(재귀, 트리 순회)
  • 파일 시스템, 조직도, UI 컴포넌트 트리, 문서의 중첩 구조처럼 부분-전체 관계에 잘 맞는다
  • 모든 노드에 같은 인터페이스를 강제하다 보면 잎에 의미 없는 addChild() 같은 메서드가 생긴다. 공통 연산만 인터페이스에 두고 자식 관리는 가지에만 둔다

React의 컴포넌트 트리 자체가 이 구조다. 컴포넌트가 다른 컴포넌트를 children으로 품고, 어느 깊이에서든 같은 방식으로 렌더링된다(React 엘리먼트와 JSX). 이를 API 설계로 끌어올린 것이 컴파운드 컴포넌트다. 구조 패턴 전체는 구조 패턴.

출처: Composite — Refactoring.Guru

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 퍼사드 패턴

    복잡한 하위 시스템 앞에 단순한 창구 하나를 세워, 호출자가 내부의 여러 객체와 호출 순서를 몰라도 되게 하는 패턴.

  • 디자인 패턴

    반복해서 나타나는 설계 문제에 대한 검증된 해결 구조와 그 이름. 복사해 쓰는 완성 코드가 아니라 객체들이 협력하는 방식을 설명하는 어휘다. 1994년 이른바 GoF(Gang of Four, 네 명의 저자)의 책 『Design Patterns: Elements of Reusable Object-Oriented Software』가 23개 패턴을 정리하며 널리 퍼졌다.

  • 코드 냄새

    당장 버그는 아니지만 이해나 변경 비용을 높이는 구조적 신호. 리팩터링을 언제 시작하고 멈출지에 정확한 공식은 없어서, 냄새라는 어휘로 직관을 공유한다.

  • 특이 케이스와 널 객체

    특정 값(가장 흔하게는 null이나 "미확인" 같은 표시값)을 만날 때마다 같은 처리를 하는 코드가 곳곳에 흩어져 있을 때, 그 경우를 대표하는 객체를 하나 만들어 공통 동작을 담는 패턴. null을 대표하면 널 객체(Null Object)라 부르며, 널 객체는 특이 케이스(Special Case)의 한 예다.

  • 템플릿 메서드 패턴

    알고리즘의 뼈대(단계의 순서)는 상위 클래스의 메서드에 고정하고, 일부 단계만 하위 클래스가 바꾸게 하는 패턴.

보기 옵션