반응형
컴포지트 패턴(Composite Pattern) 으로 객체를 트리구조로 구성해서 부분-전체 계층구조를 구현합니다. 컴포지트 패턴을 사용하면 클라이언트에서 개별 객체와 복합 객체를 똑같은 방법으로 다룰 수 있습니다.
이 패턴을 사용하면 중첩되어 있는 그룹과 항목을 똑같은 구조 내에서 처리 할 수 있습니다. 그룹과 항목을 같은 구조에 넣어서 부분 - 전체 계층 구조(part-whole hierarchy)를 생성할 수 있습니다.
여기서 부분 - 전체 계층 구조란, 부분들이 계층을 이루고 있지만 모든 부분을 묶어서 전체로 다룰 수 있는 구조를 말합니다.
- 컴포지트 패턴을 사용하면 객체의 구성과 개별 객체를 노드로 가지는 트리 형태의 객체 구조를 만들 수 있습니다.
- 이런 복합 구조(composite structure)를 사용하면 복합 객체와 개별 객체를 대상으로 똑같은 작업을 적용할 수 있습니다.
- 즉, 복합 객체와 개별 객체를 구분할 필요가 거의 없어집니다.
package pattern.composite;
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 double getPrice() {
throw new UnsupportedOperationException();
}
public boolean isVegetarian() {
throw new UnsupportedOperationException();
}
public void print() {
throw new UnsupportedOperationException();
}
}
package pattern.composite;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Menu extends MenuComponent {
List<MenuComponent> menuComponents = new ArrayList<MenuComponent>();
String name;
String description;
public Menu(String name, String description) {
this.name = name;
this.description = description;
}
public void add(MenuComponent menuComponent) {
menuComponents.add(menuComponent);
}
public void remove(MenuComponent menuComponent) {
menuComponents.remove(menuComponent);
}
public MenuComponent getChild(int i) {
return menuComponents.get(i);
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
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();
}
}
}
package pattern.composite;
public class MenuItem extends 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;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public double getPrice() {
return price;
}
public boolean isVegetarian() {
return vegetarian;
}
public void print() {
System.out.print(" " + getName());
if (isVegetarian()) {
System.out.print("(v)");
}
System.out.println(", " + getPrice());
System.out.println(" -- " + getDescription());
}
}
package pattern.composite;
public class Waitress {
MenuComponent allMenus;
public Waitress(MenuComponent allMenus) {
this.allMenus = allMenus;
}
public void printMenu() {
allMenus.print();
}
}
package pattern.composite;
public class MenuTestDrive {
public MenuTestDrive() {
MenuComponent pancakeHouseMenu =
new Menu("팬케이크 하우스 메뉴", "아침메뉴");
MenuComponent dinerMenu =
new Menu("객체마을 식당 메뉴", "점심 메뉴");
MenuComponent cafeMenu =
new Menu("카페 메뉴", "저녁 메뉴 ");
MenuComponent dessertMenu =
new Menu("디저트 메뉴", "디저트를 즐겨 보세요!");
// MenuComponent coffeeMenu = new Menu("커피 메뉴", "Stuff to go with your afternoon coffee");
MenuComponent allMenus = new Menu("전체 메뉴", "전체 메뉴");
allMenus.add(pancakeHouseMenu);
allMenus.add(dinerMenu);
allMenus.add(cafeMenu);
pancakeHouseMenu.add(new MenuItem(
"K&B 팬케이크 세트",
"스크램블 에그",
true,
2.99));
pancakeHouseMenu.add(new MenuItem(
"레귤러 팬케이크 세트",
"달걀",
false,
2.99));
pancakeHouseMenu.add(new MenuItem(
"블루베리 팬케이크",
"신선한 블루베리",
true,
3.49));
pancakeHouseMenu.add(new MenuItem(
"와플",
"취향에 따라 .. 와플",
true,
3.5));
dinerMenu.add(new MenuItem(
"채식주의자용 BLT",
"통밀 위에 콩고기 베이컨...",
true,
2.99));
dinerMenu.add(new MenuItem(
"BLT",
"통 밀위에 베이컨 ..",
false,
2.99));
dinerMenu.add(new MenuItem(
"오늘의 스프",
"감자 샐러드로...",
false,
3.29));
dinerMenu.add(new MenuItem(
"핫도그",
"핫도그..임",
false,
3.05));
dinerMenu.add(new MenuItem(
"찐 채소와 브라운 라이스",
"찐 채소와 라이스...",
true,
3.99));
dinerMenu.add(new MenuItem(
"파스타",
"마리나라 소스 스파게티 ...",
true,
3.89));
dinerMenu.add(dessertMenu);
dessertMenu.add(new MenuItem(
"애플 파이",
"애플 파이..",
true,
1.59));
dessertMenu.add(new MenuItem(
"치즈케이크",
"뉴욕 치즈케이크",
true,
1.99));
dessertMenu.add(new MenuItem(
"소르베",
"라스베리와 라임의 절묘한 조화",
true,
1.89));
cafeMenu.add(new MenuItem(
"배지 버거와 에어 프라이",
"배지 버거와 에어 프라이...",
true,
3.99));
cafeMenu.add(new MenuItem(
"오늘의 스프",
"오늘의 스프",
false,
3.69));
cafeMenu.add(new MenuItem(
"브리토",
"콩과 살사, 부리토",
true,
4.29));
Waitress waitress = new Waitress(allMenus);
waitress.printMenu();
}
}
- 컴포지트 패턴에서는 단일 역할 원칙을 깨는 대신 투명성을 확보하는 패턴이라고 할 수 있다.
- 투명성(transparency)란 Component 인터페이스에 자식들을 관리하는 기능과 잎으로써의 기능을 전부 넣어서 클라이어늩가 복합 객체와 잎을 똑같은 방식으로 처리할 수 있도록 만들 수 있다.
- 상황에 따라 원칙을 적절하게 사용해야 함을 보여 주는 대표 사례라고 볼 수 있다.
반응형
'Delvelopment > DesignPattern' 카테고리의 다른 글
[Design Pattern] 반복자 패턴 (Iterator Pattern) (0) | 2022.07.09 |
---|---|
[Design Pattern] 팩토리 메소드 패턴 (Factory Method Pattern) (0) | 2022.07.03 |
[Design Pattern] 퍼사드 패턴 (Facade Pattern) (0) | 2022.07.03 |
[Design Pattern] 적응자 패턴 (Adapter Pattern) (0) | 2022.07.03 |
[Design Pattern] 커맨드 패턴 (Command Pattern) (0) | 2022.07.03 |
댓글