dev/🧩 디자인패턴

컴포지트 패턴이란? (Composite Pattern)

wugawuga 2023. 1. 12. 21:32

컴포지트 패턴이란?

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

 

컴포지트 패턴의 구조

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. 재귀호출을 하기 때문에 트리 깊이가 깊어질 수록 디버깅이 어렵다