개발 도서

디자인 패턴 - 컴포지트 패턴

백수왕 2023. 12. 19. 17:04

컴포지트 패턴

객체를 트리구조로 구성해서 부분-전체 계층구조를 구현합니다.컴포지트 패턴을 사용하면 클라이언트에서 개별 객체와 복합 객체를 똑같은 방법으로 다룰 수 있습니다.

 

즉, 단일객체와 집합객체를 하나의 동일한 방법으로 처리하기 위한 패턴입니다. 

 

특징

  • 컴포지트 패턴은 객체들을 부분-전체 계층 구조로 구성합니다.
  • 새로운 객체를 추가하거나 구조를 변경해도 클라이언트 코드를 수정할 필요가 없습니다.
  • 복합 객체와 개별 객체를 대상으로 똑같은 작업을 적용할 수 있어 구분할 필요가 없어진다.

장점

  • 일관성 있는 인터페이스를 제공합니다.
  • 시스템이 유연하고 확장 가능합니다.

단점

  • 특정한 복합 객체에 특화된 메서드를 호출하기 어려울 수 있습니다.
  • 일부 상황에서는 설계가 복잡해질 수 있습니다. ex) 실제로 구분하여 처리해야 하는 경우

 

컴포지트 패턴 사용 예제

 

abstract class PlaylistComponent {
    protected String name;

    public PlaylistComponent(String name) {
        this.name = name;
    }

    public abstract void display();
}

Playlist는 컴포지트 패턴의 구성 요소를 나타내는 추상 클래스입니다.

 

class Music extends PlaylistComponent {
    public Music(String name) {
        super(name);
    }

    @Override
    public void display() {
        System.out.println(name + "재생중");
    }
}

현재 플레이리스트에서 재생중인 노래를 출력합니다.

class Playlist extends PlaylistComponent {

    private List<PlaylistComponent> playlistComponents = new ArrayList<>();

    public Playlist(String name) {
        super(name);
    }

    public void add(PlaylistComponent component) {
        playlistComponents.add(component);
    }

    public void remove(PlaylistComponent component) {
        playlistComponents.remove(component);
    }

    @Override
    public void display() {
        System.out.println("현재 플레이리스트 : " + name);

        for (PlaylistComponent component : playlistComponents) {
            component.display();
        }
    }
}

여러 노래나 중첩된 플레이리스트를 담을 수 있는 복합 객체입니다. 

 

display 메서드에서는 현재 플레이리스트의 정보를 출력하고 자식 요소들의 display 메서드를 호출하여 구조를 출력합니다.

 

public class Test {
    public static void main(String[] args) {
        PlaylistComponent superShy = new Music("SuperShy");
        PlaylistComponent oacbn = new Music("On a cherry Blossom Night");

        Playlist KPop = new Playlist("K팝");
        Playlist JPop = new Playlist("J팝");

        KPop.add(superShy);
        JPop.add(oacbn);

        Playlist mainPlaylist = new Playlist("루트 플레이리스트");
        mainPlaylist.add(KPop);
        mainPlaylist.add(JPop);

        mainPlaylist.display();
    }
}