Java/Design Pattern

[헤드퍼스트 디자인 패턴] 9-2. 컴포지트 패턴

noahkim_ 2024. 12. 18. 21:11

에릭 프리먼 님의 "헤드퍼스트 디자인 패턴" 책을 정리한 포스팅 입니다

 

1. 컴포지트 패턴

  • 객체를 트리구조로 구성해서 부분-전체 계층구조를 구현한 패턴
  • 리프와 컴포지트 객체를 동일한 인터페이스로 다룰 수 있음

 

장점

장점 설명
일관된 처리 방식
개별 객체와 복합 객체를 같은 방식으로 다룰 수 있음 (e.g., draw(), getPrice() 등)
투명성 확보
클라이언트는 리프인지 컴포지트인지 신경 쓰지 않고 동일한 방식으로 호출 가능
확장성 높음
새로운 리프나 복합 객체를 손쉽게 추가 가능 → 구조 변경이 쉬움

 

단점

단점 설명
단일 책임 원칙 위반
컴포지트 객체가 계층 관리 + 데이터 보관까지 함께 담당하게 됨
불필요한 메서드 강제
리프 노드에도 필요 없는 메서드를 구현해야 할 수 있음 → 인터페이스 오염

 

2. 예제: MenuComponent

MenuComponent (abstract)

  • 노드의 추상클래스
  • 내부 노드와 리프 노드가 서로 역할이 다르므로 기본적으로 예외를 던지도록 함
더보기
public abstract class MenuComponent {
    public void add(MenuComponent menuComponent) { throw new UnsupportedOperationException(); }
    public void remove(MenuComponent menuComponent) { throw new UnsupportedOperationException(); }
    public MenuComponent getChild(int i) { throw new UnsupportedOperationException(); }
    public String getName() { throw new UnsupportedOperationException(); }
    public String getDescription() { throw new UnsupportedOperationException(); }
    public String getPrice() { throw new UnsupportedOperationException(); }
    public String isVegitarian() { throw new UnsupportedOperationException(); }
    public void print() { throw new UnsupportedOperationException(); }
}

 

Menu (Node)

더보기
public class Menu extends MenuComponent {
    List<MenuComponent> menuComponents = new ArrayList<>();    
    String name, description;
    
    // constructor
    // getter, setter
    public void print() { /* 상태 출력 */ }

    public void add(MenuComponent menuComponent) { menuComponents.add(menuComponent); }
    public void remove(MenuComponent menuComponent) { menuComponents.remove(menuComponent); }
    public MenuComponent getChild(int i) { menuComponents.get(i); }    
}

 

MeunItem (Leaf)

더보기
public class MenuItem extends MenuComponent {
    String name, description;
    boolean vegetarian;
    double price;
    
    // constructor
    // getter, setter
    
    public void print() { /* 상태 출력 */ }
}