[typescript] 객체들의 계층 구조를 표현하는 동시에 동일한 방식으로 접근하는 컴포지트 패턴과 타입스크립트의 결합 사례

컴포지트 패턴은 객체들의 계층 구조를 표현하는 패턴으로, Leaf와 Composite로 구성되어 있다. Leaf는 더 이상 분해되지 않는 단일 객체를 나타내고, Composite는 Leaf나 다른 Composite를 자식으로 가지며, 자식들에 대해 일관된 방식으로 작업할 수 있는 구조를 가지고 있다.

타입스크립트는 정적 타입을 지원하는 자바스크립트 슈퍼셋으로, 컴포지트 패턴을 효과적으로 구현할 수 있는 풍부한 타입 시스템을 제공한다. 이번 글에서는 컴포지트 패턴을 사용하여 객체들의 계층 구조를 표현하고, 타입스크립트의 강력한 타입 시스템을 활용하여 동일한 방식으로 이 구조에 접근하는 방법을 살펴볼 것이다.

Leaf와 Composite 정의하기

먼저, Leaf와 Composite를 타입스크립트로 정의해보자.

type TreeNode<T> = {
  value: T;
};

type Tree<T> = TreeNode<T> & {
  children: (TreeNode<T> | Tree<T>)[];
};

여기서 TreeNode은 Leaf를 나타내고, 단일 값인 value를 가진다. Tree는 Composite를 나타내며, 자식 요소들을 가지는 children 필드를 추가로 가진다.

일관된 방식으로 작업하기

이제, Leaf와 Composite를 활용하여 일관된 방식으로 작업하는 예제를 살펴보자.

function processTree<T>(node: TreeNode<T> | Tree<T>): void {
  console.log(node.value);

  if ('children' in node) {
    for (const child of node.children) {
      processTree(child);
    }
  }
}

const leaf1: TreeNode<string> = { value: 'leaf 1' };
const leaf2: TreeNode<string> = { value: 'leaf 2' };

const tree: Tree<string> = {
  value: 'root',
  children: [leaf1, leaf2, {
    value: 'subtree',
    children: [ { value: 'leaf 3' } ]
  }],
};

processTree(tree);

위 예제에서 processTree 함수는 Leaf나 Composite에 대해 동일한 방식으로 작업한다. Leaf일 경우에는 단순히 값을 출력하고, Composite일 경우에는 자식 요소들에 대해 재귀적으로 processTree 함수를 호출한다.

결론

이렇게 타입스크립트의 강력한 타입 시스템을 활용하여 컴포지트 패턴을 구현하고, 동일한 방식으로 객체들의 계층 구조에 접근하는 방법을 살펴보았다. 이는 유연하고 확장 가능한 애플리케이션을 구축하는데 도움이 될 것이다.