단일 객체와 복합 객체를 같은 타입으로 취급하며, 트리 구조로 객체들을 엮는 패턴이다.
Component
operation()
을 구현할 수 있음Leaf
Composite
식당 메뉴 저장 프로그램
MenuItem
: leaf에 해당하는 클래스 (개별 객체)Menu
: MenuComponent를 구현하면서, MenuComponent를 포함할 수 있음MenuComponent Component
public interface MenuComponent {
// // add() 를 통해 자식으로 여러 개의 "Leaf" 를 가질 수 있음
public default void add(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}
public default void remove(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}
public default MenuComponent getChild(int i) {
throw new UnsupportedOperationException();
}
public default String getName() {
throw new UnsupportedOperationException();
}
public 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();
}
}
MenuItem Leaf
public class MenuItem implements MenuComponent {
String name;
String description;
boolean vegetarian;
double price;
public MenuItem(String name, String description,
boolean vegetarian, double price) {
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
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.print(" " + getName());
if (isVegetarian()) {
System.out.print("(v)");
}
System.out.println(", " + getPrice());
System.out.println(" -- " + getDescription());
}
}
Menu Composite
public class Menu implements MenuComponent {
// 인터페이스 "MenuComponent" 를 구현하는 요소들을 관리하기 위한 리스트
// menuComponents를 여러개 가질 수 있으므로 arraylist를 이용하여 담을 수 있게 함
ArrayList<MenuComponent> menuComponents = new ArrayList<>();
String name;
String description;
public Menu(String name, String description) {
this.name = name;
this.description = description;
}
@Override
public void add(MenuComponent menuComponent) {
menuComponents.add(menuComponent);
}
@Override
public void remove(MenuComponent menuComponent) {
menuComponents.remove(menuComponent);
}
@Override
public MenuComponent getChild(int i) {
return (MenuComponent) menuComponent.get(i);
}
@Override
public String getName() {
return name;
}
@Override
public String getDescription() {
return description;
}
@Override
public void print() {
System.out.print("\n" + getName());
System.out.println(", " + getDescription());
System.out.println("--------------------------");
// 메뉴 컴포넌트에 있는 것들을 하나씩 취급해서 출력하는 형태
Iterator<MenuComponent> iterator = menuComponents.iterator();
while (iterator.hasNext()) {
MenuComponent menuComponent = iterator.next();
menuComponent.print();
}
}
}
Waitron
public class Waitron {
MenuComponent allMenus;
// 어떤 메뉴를 전달할건지
public Waitron(MenuComponent allMenus) {
this.allMenus = allMenus;
}
// 메뉴 출력
public void printMenu() {
allMenus.print();
}
}
Main
public class MenuTestDrive {
public static void main(String[] args) {
MenuComponent pancakeHouseMenu = new Menu("팬케이크 하우스 메뉴", "아침 메뉴");
MenuComponent dinerMenu = new Menu("객체마을 식당 메뉴", "점심 메뉴");
MenuComponent cafeMenu = new Menu("카페 메뉴", "저녁 메뉴");
MenuComponent dessertMenu = new Menu("디저트 메뉴", "디저트를 즐기세요!");
MenuComponent allMenus = new Menu("전체 메뉴", "전체 메뉴");
allMenus.add(pancakeHouseMenu);
allMenus.add(dinerMenu);
allMenus.add(cafeMenu);
dinerMenu.add(new MenuItem("파스타", "마리나라 소스 스파게티, 효모빵 포함", true, 3.89));
dinerMenu.add(new MenuItem("애플 파이", "바삭바삭한 크러스트에 바닐라 아이스크림이 얹혀있는 애플 파이", true, 1.59));
// dissertMenu가 MenuComponent를 구성하는 형태이므로 메뉴 항목인 것처럼 넣기 가능
dinerMenu.add(dessertMenu);
Waitron waitron= new Waitron(allMenus);
waitron.printMenu();
}
}
실행 화면