티스토리 뷰

디자인 패턴

08. 컴포짓 패턴

jin-park 2022. 2. 10. 17:18

1. 의미

  • 그룹 전체와 개별 객체를 동일하게 처리할 수 있는 패턴
  • 클라이언트 입장에서는 '전체'나 '부분'이나 모두 동일한 컴포넌트로 인식할 수 있는 계층 구조를 만든다.(Part-Whole Hierarchy)

다이어그램

2. 예제

  • 가방 내부에 존재하는 아이템의 가격 계산 작성.

2.1. 패턴 적용 이전

public class Item {
    private String name;
    private int price;
 
    public Item(String name, int price) {
        this.name = name;
        this.price = price;
    }
 
    public String getName() {
        return name;
    }
 
    public int getPrice() {
        return price;
    }
}
public class Bag {
    private List<Item> items = new ArrayList<>();
 
    public void add(Item item) {
        items.add(item);
    }
 
    public List<Item> getItems() {
        return items;
    }
}
public class Client {
    public static void main(String[] args) {
        // before
        Item doranBlade = new Item("도란검", 450);
        Item healPotion = new Item("체력 물약", 50);
 
        Bag bag = new Bag();
        bag.add(doranBlade);
        bag.add(healPotion);
 
        Client client = new Client();
        client.printPrice(doranBlade);
        client.printPrice(bag);
    }
 
    private void printPrice(Item item) {
        System.out.println(item.getPrice());
    }
 
    private void printPrice(Bag bag) {
        int sum = bag.getItems().stream().mapToInt(Item::getPrice).sum();
        System.out.println(sum);
    }
}

2.2 패턴 적용 이후

public interface Component {
    int getPrice();
}
public class ItemAdvanced implements Component {
    private String name;
    private int price;
 
    public ItemAdvanced(String name, int price) {
        this.name = name;
        this.price = price;
    }
 
    @Override
    public int getPrice() {
        return this.price;
    }
}
public class BagAdvanced 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) {
        // after
        ItemAdvanced doranBladeAVC = new ItemAdvanced("도란검", 450);
        ItemAdvanced healPotionAVC = new ItemAdvanced("체력 물약", 50);
 
        BagAdvanced bagAVC = new BagAdvanced();
        bagAVC.add(doranBladeAVC);
        bagAVC.add(healPotionAVC);
 
        client.printPriceAdvanced(doranBladeAVC);
        client.printPriceAdvanced(bagAVC);
    }
 
    private void printPriceAdvanced(Component component) {
        System.out.println(component.getPrice());
    }
}

3. 장점 및 단점

3. 1. 장점

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

3. 2. 단점

  • 트리를 만들어야 하기 때문에 (공통된 인터페이스를 정의해야 되기 때문에) 지나치게 일반화 해야 하는 경우도 생길 수 있다.

위글은 인프런의 코딩으로 학습하는 GoF의 디자인 패턴강의를 정리하였습니다.

백기선님의 수락으로 정리하였으며 더 자세한 내용은 강의를 수강하시기 바랍니다.

https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard

 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com

 

'디자인 패턴' 카테고리의 다른 글

10. 퍼사드 패턴  (0) 2022.02.10
09. 데코레이터 패턴  (0) 2022.02.10
07. 브릿지 패턴  (0) 2022.02.10
06. 어댑터 패턴  (0) 2022.02.10
05. 프로토타입 패턴  (0) 2022.02.10
댓글