728x90
반응형

Composite Pattern 이란?

- 객체를 트리구조로 구성해서 부분-전체 계층구조를 구현한다.

- 클라이언트에서 개별 객체와 복합 객체를 똑같은 방법으로 다룰 수 있다.

 

윈도우의 디렉토리 구조를 생각하면 쉽다. 폴더에는 폴더 또는 파일이 들어갈 수 있으며 개별 객체(파일), 복합 객체(폴더)를 똑같은 방법으로 다룰 수 있는 구조가 Composite Pattern 이라고 생각하면 된다!

 

Component

- 개별 객체 뿐만 아니라 이런한 개별 객체들을 계층 구조로 포함하는 복합 객체를 나타내는 인터페이스 또는 추상 클래스

- 모든 클래스에 공통적인 행위에 대해 기본 기능을 구현할 수 있다.

Leaf (개별 객체)

- 개별 객체에 해당되는 컴포넌트

Composite (복합 객체)

- 다른 컴포넌트를 포함할 수 있는 컴포넌트

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

 

예시

맥도날드에서 메뉴판을 보면 불고기 버거 단품, 감자 튀김, 불고기 버거 세트 메뉴, 패밀리 세트 메뉴 등 다양한 메뉴가 존재한다. 이 때, 햄버거와 감자튀김은 단일 메뉴로서 역할을 할 수도 있고 버거 세트 메뉴로서 하나의 메뉴에 포함될 수도 있다. 이 때, 햄버거는 개별 객체(Leaf)로서 버거 세트 메뉴는 복합 객체(Composite)으로 비유할 수 있고 손님은 이 둘을 똑같은 방식으로 다룰 수 있다.

 

Component

public interface MenuComponent {
    public default void add(MenuComponent comp){
        throw new UnsupportedOperationException();
    }
    public default void remove(MenuComponent comp){
        throw new UnsupportedOperationException();
    }
    public default MenuComponent getChild(int i){
        throw new UnsupportedOperationException();
    }
    public default String getName(){
        throw new UnsupportedOperationException();
    }
    public default String getDescription(){
        throw new UnsupportedOperationException();
    }

    public default double getPrice(){
        throw new UnsupportedOperationException();
    }
    public default boolean isVegetarian(){
        throw new UnsupportedOperationException();
    }
    public default void print(){
        throw new UnsupportedOperationException();
    }
}

 

Leaf

public class MenuItem implements MenuComponent{
    String name;
    String description;
    boolean vegetarian;
    double price;

    public MenuItem(String name, String desc, boolean vege, double price){
        this.name = name;
        this.description = desc;
        this.vegetarian = vege;
        this.price = price;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getDescription() {
        return description;
    }

    @Override
    public boolean isVegetarian() {
        return vegetarian;
    }

    @Override
    public double getPrice() {
        return price;
    }

    @Override
    public void print() {
        System.out.println(" "+getName());
        if(isVegetarian()){
            System.out.println("(v)");
        }
        System.out.println(", "+getPrice());
        System.out.println("    -- "+getDescription());
    }
}

 

Composite

public class Menu implements MenuComponent{
    ArrayList<MenuComponent> menuComponents = new ArrayList();
    String name;
    String description;

    public Menu(String name, String description) {
        this.name = name;
        this.description = description;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getDescription() {
        return description;
    }

    @Override
    public void add(MenuComponent comp) {
        menuComponents.add(comp);
    }

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

    public void print() {
        System.out.print("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("---------------------");
        Iterator it = menuComponents.iterator();
        while (it.hasNext()) {
            MenuComponent component
                    = (MenuComponent) it.next();
            component.print();
        }
    }

}

 

728x90
반응형

+ Recent posts