컴포짓(composite) 패턴

컴포짓 패턴은 객체들을 트리 구조로 구성하여 단일 객체와 복합 객체를 동일하게 다룰 수 있는 디자인 패턴입니다.
이 패턴을 사용하면 개별 객체와 그들의 조합체를 일관된 방식으로 다룰 수 있으며, 계층 구조를 표현하고 조작할 수 있습니다.

구성 요소

컴포넌트(Component): 복합 객체와 단일 객체의 공통 인터페이스를 정의합니다.
리프(Leaf): 단일 객체를 나타내며, 컴포넌트의 하위 클래스입니다.
컨테이너(Container): 복합 객체를 나타내며, 컴포넌트를 추가, 삭제 또는 접근할 수 있습니다.

구현:

  1. 컴포넌트 인터페이스를 정의합니다. 이 인터페이스는 리프와 컨테이너 클래스에 의해 구현됩니다.
  2. 리프 클래스를 생성하여 단일 객체를 나타냅니다. 이 클래스는 컴포넌트 인터페이스를 구현합니다.
  3. 컨테이너 클래스를 생성하여 복합 객체를 나타냅니다. 이 클래스는 컴포넌트 인터페이스를 구현하며, 자식 컴포넌트를 추가, 삭제 또는 접근할 수 있는 메서드를 구현합니다.
  4. 클라이언트에서는 컴포넌트 인터페이스를 사용하여 단일 객체와 복합 객체를 동일하게 다룰 수 있습니다.

장점

개별 객체와 복합 객체를 일관된 방식으로 다룰 수 있습니다.
계층 구조를 표현하고 조작할 수 있습니다.
새로운 객체를 추가하기 쉽고 유연성이 향상됩니다.

단점

구조가 복잡해질 수 있으며, 관리와 유지보수에 주의가 필요합니다.

예시

여러 아이템이 들어있는 가방의 아이템 총 가격과 아이템 이름을 확인해야한다.

Component

public interface Item {

    int getPrice();

    String getName();
}

Leaf

public class HealPotion implements Item{
    @Override
    public int getPrice() {
        return 50;
    }

    @Override
    public String getName() {
        return "체력 물약";
    }
}

public class DoranBlade implements Item{
    @Override
    public int getPrice() {
        return 450;
    }

    @Override
    public String getName() {
        return "도란검";
    }
}

public class BloodBlade implements Item{
    @Override
    public int getPrice() {
        return 350;
    }

    @Override
    public String getName() {
        return "흡혈검";
    }
}

Container

public class Bag implements Item {

    private final List<Item> items = new ArrayList<>();

    public void add(Item item) {
        items.add(item);
    }

    public List<Item> getItems() {
        return items;
    }

    @Override
    public int getPrice() {
        return items.stream().mapToInt(Item::getPrice).sum();
    }

    @Override
    public String getName() {
        return items.stream()
                .map(item -> "["+item.getName()+"]")
                .collect(Collectors.joining(", "));
    }
}

Client

class BagTest {
    @Test
    public void getDoranBladeAndHealPotionPriceTest() {
        Bag bag = new Bag();
        bag.add(new DoranBlade());
        bag.add(new HealPotion());
        bag.add(new HealPotion());

        int price = bag.getPrice();
        System.out.println(bag.getName());
        assertEquals(price, 550);
    }

    @Test
    public void getBloodBladeAndHealPotionPrice() {
        Bag bag = new Bag();
        bag.add(new BloodBlade());
        bag.add(new HealPotion());

        int price = bag.getPrice();
        System.out.println(bag.getName());
        assertEquals(price, 400);
    }
}

결론

컴포짓 패턴은 객체들을 트리 구조로 구성하여 단일 객체와 복합 객체를 동일하게 다룰 수 있는 디자인 패턴입니다.
이를 통해 개별 객체와 그들의 조합체를 일관된 방식으로 다룰 수 있으며, 계층 구조를 표현하고 조작할 수 있습니다.
그러나 구조가 복잡해지고 관리와 유지보수에 주의가 필요합니다.

예제는 이곳 에서 확인하실수 있습니다.