본문 바로가기
컴퓨터과학/디자인패턴

[디자인패턴] 컴포짓 패턴 (Composite Pattern)

by 윤호 2021. 12. 13.

목적

클라이언트가 각 객체와 객체의 묶음을 동일하게 다룰 수 있도록

요소

문제 : 프로그램에서 각각의 객체(개별 객체) 또는 계층 구조로 이루어진 객체 묶음(복합 객체)을 다뤄야 함

해결 : 개별 객체와 복합 객체에 대해 동일한 작업을 적용. 대부분의 경우에 개별 객체와 복합 객체의 차이를 무시할 수 있도록 함

결과 : 유지보수에 유리

정의

컴포넌트

  • 개별 객체와 개별 객체들을 계층 구조로 포함하는 복함 객체를 나타내는 인터페이스 또는 추상 클래스

개별 객체(Leaf)

  • 다른 컴포넌트를 포함할 수 없는 컴포넌트

복합 객체(Composite)

  • 개별 객체 또는 다른 복합 객체를 포함할 수 있음

컴포짓 패턴을 이용한 메뉴 디자인

MenuItem은 개별객체(Leaf), Menu는 복합 객체(Composite)

 

모든 컴포넌트를 waitron에 담아서 사용한다.

public class Waitron {
    MenuComponent allMenus;

    public Waitron(MenuComponent allMenus) {
        this.allMenus = allMenus;
    }

    public void printMenu() {
        allMenus.print();
    }
}

 

인터페이스 MenuComponent의 메소드들은 default 메소드로 만들어서 모두 구현을 안해도 되게끔 한다.

public interface MenuComponent {
    public default void add(MenuComponent comp) {
    	throw new UnsupportedOperationException(); 
    }
    ...
}

 

개별 객체(Leaf)

class MenuItem implements MenuComponent{
    String name;
    String description;
    boolean vegetarian;
    double price;
    ...
    public void print() {
        System.out.print(" " + getName());
        if (isVegetarian()) {
            System.out.print("(v)");
        }
        System.out.println(", " + getPrice());
        System.out.println(" -- " + getDescription());
    }
}

 

복합 객체(Composite)

class Menu implements MenuComponent {
    ArrayList menuComponents = new ArrayList();
    String name;
    String description;
    ...
    public void add(MenuComponent comp) {
        menuComponents.add(comp);
    }

    public void remove(MenuComponent comp) {
        menuComponents.remove(comp);
    }

    public void print() {
        System.out.println("\n" + getName() + ", " + getDescription());
        System.out.println("---------------------");
        for (MenuComponent component : menuComponents) {
            component.print();
        }
    }
}

 

컴포짓 패턴을 사용한 메인 함수

MenuComponent pancakeHouseMenu = new Menu("팬케이크 하우스 메뉴", "아침 메뉴");
MenuComponent dinerMenu = new Menu("객체마을 식당 메뉴", "점심 메뉴");
MenuComponent cafeMenu = new Menu("카페 메뉴", "저녁 메뉴");
MenuComponent dessertMenu = new Menu("디저트 메뉴", "디저트를 즐기세요!");
MenuComponent allMenus = new Menu("전체 메뉴", "전체 메뉴");

MenuComponent pasta = new MenuItem("파스타", "마리나라 소스 스파게티, 효모빵 포함", true, 3.89);
MenuComponent applePie = new MenuItem("애플 파이", "바삭바삭한 크러스트에 바닐라 아이스크림이 얹혀 있는 애플 파이", true, 1.59);

allMenus.add(pancakeHouseMenu);
allMenus.add(dinerMenu);
allMenus.add(cafeMenu);

dinerMenu.add(pasta);
dinerMenu.add(dessertMenu);
dessertMenu.add(applePie);

// 메뉴 항목들 추가
Waitron waitron = new Waitron(allMenus);
waitron.printMenu();

 

실행 결과

 

댓글