컴포지트 패턴이란?

구조 패턴 중 하나
객체들의 관계를 트리 구조로 구성해서, 부분 - 전체 계층을 표현하는 패턴
클라이언트에서 개별 객체와 복합 객체를 똑같은 방법으로 다룰 수 있다

 

컴포지트 패턴의 구조

Component, Composite, Leaf 으로 볼 수 있다

  • Component : Composite 과 Leaf 의 인터페이스
  • Composite : 구현 클래스, Leaf (구현되는 자식들), 자식들을 관리하는 메소드 구현
  • Leaf : 구현 클래스, 자식을 가지지 않음

 

패턴 적용

폴더와 파일 구조를 컴포지트 패턴으로 작성을 해보자

root 폴더

  • home
    • wuga
    • music
      • track1 (파일)
      • track2 (파일)
    • doc
      • doc1 (파일)
    • picture
      • pic1 (파일)
  • usr
    • java (파일)

 

Component 에 해당하는 코드

public abstract class Component {

    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

Composite 에 해당하는 코드

public class Folder extends Component {

    List<Component> children = new ArrayList<>();

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

    public boolean addComponent(Component component) {
        return children.add(component);
    }

    public boolean removeComponent(Component component) {
        return children.remove(component);
    }

    public List<Component> getChildren() {
        return children;
    }
}

 

Leaf 에 해당하는 코드

public class File extends Component {

    private Object data;

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

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

 

메인 클래스

public class Application {

    public static void main(String[] args) {
        Folder root = new Folder("root");
        Folder home = new Folder("home");
        Folder wuga = new Folder("wuga");
        Folder music = new Folder("music");
        Folder picture = new Folder("picture");
        Folder doc = new Folder("doc");
        Folder usr = new Folder("usr");

        File track1 = new File("track1");
        File track2 = new File("track2");
        File pic1 = new File("pic1");
        File doc1 = new File("doc1");
        File java = new File("java");

        root.addComponent(home);
        root.addComponent(usr);

        home.addComponent(wuga);
        home.addComponent(music);
        home.addComponent(picture);
        home.addComponent(doc);

        music.addComponent(track1);
        music.addComponent(track2);
        picture.addComponent(pic1);
        doc.addComponent(doc1);
        usr.addComponent(java);

        show(root);
    }

    private static void show(Component component) {
        System.out.println(component.getClass().getName() + "|" + component.getName());
        if (component instanceof Folder) {
            for (Component c : ((Folder) component).getChildren()) {
                show(c);
            }
        }
    }
}

Folder | root
Folder | home
Folder | wuga
Folder | music
File | track1
File | track2
Folder | picture
File | pic1
Folder | doc
File | doc1
Folder | usr
File | java

 

장점

  1. 추상 클래스를 상속 또는 인터페이스를 구현만 하면 되기 때문에 새로운 클래스 추가가 쉽다
  2. 코드가 단순해진다

 

단점

  1. 재귀호출을 하기 때문에 트리 깊이가 깊어질 수록 디버깅이 어렵다
복사했습니다!