Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- 파사드패턴
- 어댑터패턴
- 옵저버패턴
- 데코레이터패턴
- Xcode
- 템플릿메서드
- Lifecycle
- 컴파운드패턴
- cocoapods
- WKWebView
- Scenedelegate
- 상태패턴
- Mobile
- 전략패턴
- 커맨드패턴
- SWIFT
- 컴포지트패턴
- RxSwift
- 이터레이터패턴
- ios
- 싱글턴패턴
- unowned
- ViewController
- 프록시패턴
- 스트래터지패턴
- 스테이트패턴
- 팩토리메서드패턴
- DispatchQueue
- 디자인패턴
- 추상팩토리패턴
Archives
- Today
- Total
ios dev kangwook.
12. Composite Pattern 본문
Composite Pattern은 여러 개의 객체들로 구성된 복합 객체와 단일 객체를 클라이언트에서 같은 타입으로 취급하며, 트리 구조로 객체들을 엮는 패턴
Composite Pattern
Composite Pattern을 사용하면 객체를 트리 구조로 합성하여 부분 - 전체 계층을 나타낼 수 있다. 이를 통해 클라이언트는 단일 객체와 복합 객체의 구성을 균일하게 처리할 수 있다.
- Component : Leaf와 Composite가 구현해야하는 클래스 또는 인터페이스로, Leaf와 Composite 모두 Component라는 같은 타입으로 다뤄짐
- Leaf : 단일 객체로 Composite의 부분 객체로 들어가게 됨. 이 때 Component 형태로 들어가게 됨
- Composite : 집합 객체로 Leaf 객체나 Composite을 부분으로 둠. 이 때 Component의 형태로 들어감 → Client는 이 Composite을 통해 부분 객체를 다룰 수 있음
Composite Pattern 예제
- 식당 메뉴를 출력하는 예제
- Composite 인 Menu를 계속 늘릴 수 있기 때문에 확장하기 쉬움
- Component : MenuComponent 클래스
- MenuItem과 Menu 클래스가 구현해야하는 클래스
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();
}
}
- Leaf : MenuItem 클래스
- 단 객체인 MenuItem 클래스로 Component형태로 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());
}
}
- Composite : Menu 클래스
- 집합 객체로 Leaf나 Composite을 Component 형태로 둠
- Composite의 역할은 하위 요소가 있는 구성 요소의 동작을 정의하고 하위 요소의 속성을 저장하는 것
public class Menu extends MenuComponent {
ArrayList<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();
}
}
}
- Client : Waitress 클래스
- Client는 Component 클래스를 참조해서 메소드를 호출
public class Waitress {
MenuComponent allMenus;
public Waitress(MenuComponent allMenus) {
this.allMenus = allMenus;
}
public void printMenu() {
allMenus.print();
}
}
- Main 함수
- Component에 Menu, MenuItem 등등 추가
- **Component에 Menu와 MenuItem을 add하는 과정
- 이러한 과정들은 클린코드 측면에서 봤을 때 별로 좋지 않다고 생각
- Component에 따라서 add하는 부분을 각각 메소드나 객체에서 처리하는 것으로 하면 더 깔끔하지 않았을까 하는 생각..
- **Component에 Menu와 MenuItem을 add하는 과정
- Component에 Menu, MenuItem 등등 추가
public class MenuTest {
public static void main(String [] argS){
MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast");
MenuComponent dinerMenu = new Menu("DINER MENU", "Lunch");
MenuComponent cafeMenu = new Menu("CAFE MENU", "Dinner");
MenuComponent dessertMenu = new Menu("DESSERT MENU", "Dessert of course!");
MenuComponent allMenus = new Menu("ALL MENUS", "All menus combinded");
allMenus.add(pancakeHouseMenu);
allMenus.add(dinerMenu);
allMenus.add(cafeMenu);
pancakeHouseMenu.add(new MenuItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast",true, 2.99));
pancakeHouseMenu.add(new MenuItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99));
pancakeHouseMenu.add(new MenuItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49));
pancakeHouseMenu.add(new MenuItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59));
dinerMenu.add(new MenuItem("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99));
dinerMenu.add(new MenuItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99));
dinerMenu.add(new MenuItem("Soup of the day", "Soup of the day, with a side of potato salad", false, 3.29));
dinerMenu.add(new MenuItem("Hotdog", "A hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05));
dinerMenu.add(new MenuItem("Pasta", "Spaghetti with Marinara Sauce, and a slice of sourdough bread", true, 3.89));
dinerMenu.add(dessertMenu);
cafeMenu.add(new MenuItem("Burrito", "A large burrito, with whole pinto beans, salsa, guacamole", true, 4.29));
dessertMenu.add(new MenuItem("Apple Pie", "Apple pie with a flakey crust, topped with vanilla icecream", true, 1.59));
Waitress waitress = new Waitress(allMenus);
waitress.printMenu();
}
}
- 출력 결과
- 트리 구조로 객체들의 구성을 표현
결론
- 객체들의 관계를 트리 구조로 구성하여 부분 - 전체 계층을 표현하는 구조 패턴(Structural Pattern)
- 장점
- 객체들이 모두 같은 타입으로 취급되기 때문에 새로운 클래스 추가가 용이
- 단일 객체, 집합 객체를 구분하지 않고 코드 작성이 가능
- 단점
- 설계를 일반화시켜 객체간의 구분이나 제약이 힘들 수 있음
본문은 Head First Design Pattern (2004) 를 참고하여 공부하고 작성하였음
'Design Pattern' 카테고리의 다른 글
14. Proxy Pattern (0) | 2022.09.06 |
---|---|
13. State Pattern (0) | 2022.09.05 |
11. Iterator Pattern (0) | 2022.08.31 |
10. Template Method Pattern (0) | 2022.08.29 |
09. Facade Pattern (0) | 2022.08.27 |
Comments