컴포지트 패턴(Composite Pattern)
디자인패턴 공부하기
  • JavaScript

컴포지트 패턴(Composite Pattern)

컴포지트 패턴이란, 클래스의 구조적인 디자인 패턴으로 단일 객체와 복합 객체를 동일하게 컨트롤하도록 도와주는 패턴이다.

트리 구조에서 가장 많이 사용되고 있다.

example

디렉토리 구조를 만드는 예제를 살펴본다.

우선 파일과 디렉토리가 필요하다

class File {
  getName () {
    return this.name;
  }

  setName(name) {
    this.name = name;
  }
}

class Directory {
  getName () {
    return this.name;
  }

  setName(name) {
    this.name = name;
  }

  addFile(file) {
    if(!this.files.includes(file)) {
      return this.files.push(file);
    }

    console.log('exist file');
  }
}

이렇게 구현했다고 가정해보자.

새로운 요구사항이 생겼다. 디렉토리 안에 파일을 넣고싶다는 요구이다.
어떻게 해야할까?

디렉토리 안에는 다시 디렉토리가 들어갈 수 도 있고, 파일이 들어갈 수 도 있다.

파일 하나는 단수 객체라면 디렉토리는 복수 객체가 될 수 있다.
이러한 경우에 컴포지트 패턴을 사용하면 도움이 된다.

아래처럼 리팩토링 해보자.

class System {
  getName () {
    return this.name;
  }

  setName(name) {
    this.name = name;
  }

  getSize () {
    throw 'his function must be overridden!!'
  }

  print () {
    throw 'his function must be overridden!!'
  }
}

class Directory extends System {
  getName () {
    return this.name;
  }

  setName(name) {
    this.name = name;
  }

  addFile(file) {
    if(!this.files.includes(file)) {
      return this.files.push(file);
    }

    console.log('exist file');
  }

  print () {
    for (const file of this.files) {
      file.print();
    }
  }
}

class File extends System {
  constructor(name, size) {
    this.name = name;
    this.size = size;
  }

  getSize () {
    return this.size;
  }

  print () {
    console.log(`file name is ${this.name}`);
  }
}

System 이라는 클래스를 이용해서 단일 객체인 File과 복합 객체인 Directory를 모두 다룰 수 있게 되었다.