# 컴포짓 (Composite) 패턴

# 컴포짓 패턴이란 무엇인가요?

image

컴포지트 패턴은 클라이언트가 복합 객체(group of object) 나 단일 객체를 동일하게 처리할 수 있도록 하는 패턴이다.
여기서 컴포지트의 의도는 트리 구조로 작성하여, 전체-부분(whole-part) 관계를 표현하는 것이다.

# 언제 사용할까요?

  • 전체-부분 관계를 트리 구조로 표현하고 싶을 경우.
  • 전체-부분 관계를 클라이언트에서 부분, 관계 객체를 균일하게 처리하고 싶을 경우.
  • 전체-부분 관계를 효율적으로 정의할 때 유용하다.

TIP

컴포지트 패턴은 타입의 안정성보다는 일관성을 더 강조

# 컴포짓 패턴의 예시 코드

가정) 사용측에서 아이템의 가격도 알고 싶고, 가방에 들어있는 아이템의 가격을 전부 알고 싶은 경우.
일반적인 경우라면 아이템 가격을 getter로 가지고 오고, 가방의 경우 getter로 아이템 리스트를 가지고 와서 일일히 다 더했겠지?

  • Component : 동일한 오퍼레이션이 있어야 하는 것을 Component로 묶는다.
public interface Component {
    int getPrice();
}
  • Leaf : 컴포넌트를 구현하는 Item을 만든다.
public class Item implements Component {
    private String name;
    private int price;

    public Item(String name, int price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public int getPrice() {
        return this.price;
    }
}
  • Composite : 컴포넌트를 포함하는 Bag을 만든다.
public class Bag implements Component {
    private List<Component> components = new ArrayList<>();

    public void add(Component component) {
        components.add(component);
    }

    public List<Component> getComponents() {
        return components;
    }

    @Override
    public int getPrice() {
        return components.stream().mapToInt(Component::getPrice).sum();
    }
}
  • 실 사용 예시
public class Client {
    public static void main(String[] args) {
        Item blade = new Item("검", 450);
        Item healPotion = new Item("체력 물약", 50);

        Bag bag = new Bag();
        bag.add(blade);
        bag.add(healPotion);

        Client client = new Client();
        client.printPrice(blade);
        client.printPrice(bag);
    }

    private void printPrice(Component component) {
        System.out.println(component.getPrice());
    }
}

# 컴포짓 패턴의 장점은 무엇인가요?

  • 복잡한 트리 구조를 편리하게 사용할 수 있고, 다형성과 재귀를 활용할 수 있다.
  • 클라이언트 코드를 변경하지 않고 새로운 타입을 추가할 수 있으며, OCP를 준수한다.

# 컴포짓 패턴의 단점은 무엇인가요?

  • 트리를 만들어야 하기에 지나치게 일반화 해야 하는 경우가 발생한다.
  • 이때 굳이 컴포짓 패턴을 선택할 이유는 없게 된다.

# 컴포짓 패턴의 예시는 무엇인가요?

  • Java Swing 라이브러리

# 참고자료

출처: https://mygumi.tistory.com/343 [마이구미의 HelloWorld]
출처: https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4 [GOF 디자인패턴]