디자인 패턴 - 컴포지트 패턴
                                            
                                                
                                                
                                                
                                                
                                                
                                                 7497 단어  Design Pattern컴포지트Design Pattern
                    
컴포지트 패턴
- 
정의 
- 객체들을 트리 구조로 구성하여 전체와 부분을 계층구조로 만들 수 패턴
 
- 
사용하는 이유 및 특징 
- 객체들을 모아서 모두 똑같은 방식으로 다루고 싶을 때 사용한다. 이러한 점은 클라이언트를 단순화시킬 수 있는 장점이 있다. 
- 하나의 메소드에서 전체 구조에 대해서 반복 작업을 처리할 때 자주 사용한다. 
 
- 
방법
  
 
- 실제 적용 UML
  
 
레거시 코드
- 디렉토리 구조
  
- 레거시 코드의 문제점
- 새로운 메뉴가 추가될 때 마다 Waitress 클래스 생성자 및 Print 변경 -> 확장성 문제
- Menu 객체에 새로운 서브 Menu 추가 번거로움 -> 확장성 문제
 
public class MenuTestDrive {
    public static void main(String[] args) {
        PancakeMenu pancakeMenu = new PancakeMenu();
        DinerMenu dinerMenu = new DinerMenu();
        CafeMenu cafeMenu = new CafeMenu();
        Waitress waitress = new Waitress(pancakeMenu, dinerMenu, cafeMenu);
        waitress.printMenu();
    }
}
- Waitress
public class Waitress {
    PancakeMenu pancakeHouseMenu;
    DinerMenu dinerMenu;
    CafeMenu cafeMenu;
    public Waitress(PancakeMenu pancakeHouseMenu, DinerMenu dinerMenu, CafeMenu cafeMenu) {
        this.pancakeHouseMenu = pancakeHouseMenu;
        this.dinerMenu = dinerMenu;
        this.cafeMenu = cafeMenu;
    }
    public void printMenu() {
        Iterator pancakeIterator = pancakeHouseMenu.createIterator();
        Iterator dinerIterator = dinerMenu.createIterator();
        Iterator cafeIterator = cafeMenu.createIterator();
        System.out.println("메뉴\n---\n아침메뉴");
        printMenu(pancakeIterator);
        System.out.println("\n점심메뉴");
        printMenu(dinerIterator);
        System.out.println("\n저녁메뉴");
        printMenu(cafeIterator);
    }
    private void printMenu(Iterator iterator) {
        while (iterator.hasNext()) {
            MenuItem menuItem = (MenuItem) iterator.next();
            System.out.print(menuItem.getName() + ", ");
            System.out.print(menuItem.getPrice() + ", ");
            System.out.println(menuItem.getDescription());
        }
    }
}
개선 코드
- 
TEST CODE public class MenuTest {
   public static void main(String[] args) throws OperationNotSupportedException {
       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);
       // 메뉴 항목을 추가하는 부분
       pancakeHouseMenu.add(new MenuItem("팬케이크","블루베리 팬케이크",true,2.99));
       dinerMenu.add(new MenuItem("파스타", "올리브 파스타",true, 3.89));
       dinerMenu.add(dessertMenu);
       dessertMenu.add(new MenuItem("애플 파이", "바닐라 아이스크림이 얹혀있는 애플 파이", true, 1.59));
       Waitress waitress = new Waitress(allMenus);
       waitress.printMenu();
   }
}
 
- 
Waitress (root node) 
public class Waitress {
    MenuComponent allMenus;
    public Waitress(MenuComponent allMenus) {
        this.allMenus = allMenus;
    }
    public void printMenu() throws OperationNotSupportedException {
        allMenus.print();
    }
}
- MenuComponent 추가   
- 모든 객체에 있는 메소드 정의 및 예외처리 -> 통합 관리 
 
public abstract class MenuComponent {
    public void add(MenuComponent menuComponent) throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
    public void remove(MenuComponent menuComponent) throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
    public MenuComponent getChild(int i) throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
    public String getName() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public String getDescription() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public double getPrice() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public boolean isVegetarian() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public void print() throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
}
- Menu 구현체 
public class Menu extends MenuComponent{
    ArrayList<MenuComponent> menuComponents = new ArrayList<>();
    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);
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public String getDescription() {
        return description;
    }
    public void print() throws OperationNotSupportedException {
        System.out.print("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("---------------------");
        Iterator iterator = menuComponents.iterator();
        while (iterator.hasNext()) {
            MenuComponent menuComponent = (MenuComponent) iterator.next();
            menuComponent.print();
        }
    }
}
- MenuItem 구현체 
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;
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public String getDescription() {
        return description;
    }
    @Override
    public boolean isVegetarian() {
        return vegetarian;
    }
    @Override
    public double getPrice() {
        return price;
    }
    public void print() {
        System.out.print("   " + getName());
        if (isVegetarian()) System.out.print(" (v)");
        System.out.println(", " + getPrice());
        System.out.println("      -- " + getDescription());
    }
}
- Q&A
- Menu 및 MenuItem을 인터페이스를 사용해서 팩토리 메소드 방식으로 개선할 수 없을까??
 
Author And Source
                            
                            이 문제에 관하여(디자인 패턴 - 컴포지트 패턴), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
                                
                                https://velog.io/@ahnseongeun/디자인-패턴-컴포지트-패턴
                            
                            
                            
                                저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
                            
                            
                                
                                
                                 우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                            
                            
                        
                    
                
                
                
            
정의
- 객체들을 트리 구조로 구성하여 전체와 부분을 계층구조로 만들 수 패턴
사용하는 이유 및 특징
- 객체들을 모아서 모두 똑같은 방식으로 다루고 싶을 때 사용한다. 이러한 점은 클라이언트를 단순화시킬 수 있는 장점이 있다.
- 하나의 메소드에서 전체 구조에 대해서 반복 작업을 처리할 때 자주 사용한다.
방법

- 실제 적용 UML
  

- 새로운 메뉴가 추가될 때 마다 Waitress 클래스 생성자 및 Print 변경 -> 확장성 문제
- Menu 객체에 새로운 서브 Menu 추가 번거로움 -> 확장성 문제
public class MenuTestDrive {
    public static void main(String[] args) {
        PancakeMenu pancakeMenu = new PancakeMenu();
        DinerMenu dinerMenu = new DinerMenu();
        CafeMenu cafeMenu = new CafeMenu();
        Waitress waitress = new Waitress(pancakeMenu, dinerMenu, cafeMenu);
        waitress.printMenu();
    }
}public class Waitress {
    PancakeMenu pancakeHouseMenu;
    DinerMenu dinerMenu;
    CafeMenu cafeMenu;
    public Waitress(PancakeMenu pancakeHouseMenu, DinerMenu dinerMenu, CafeMenu cafeMenu) {
        this.pancakeHouseMenu = pancakeHouseMenu;
        this.dinerMenu = dinerMenu;
        this.cafeMenu = cafeMenu;
    }
    public void printMenu() {
        Iterator pancakeIterator = pancakeHouseMenu.createIterator();
        Iterator dinerIterator = dinerMenu.createIterator();
        Iterator cafeIterator = cafeMenu.createIterator();
        System.out.println("메뉴\n---\n아침메뉴");
        printMenu(pancakeIterator);
        System.out.println("\n점심메뉴");
        printMenu(dinerIterator);
        System.out.println("\n저녁메뉴");
        printMenu(cafeIterator);
    }
    private void printMenu(Iterator iterator) {
        while (iterator.hasNext()) {
            MenuItem menuItem = (MenuItem) iterator.next();
            System.out.print(menuItem.getName() + ", ");
            System.out.print(menuItem.getPrice() + ", ");
            System.out.println(menuItem.getDescription());
        }
    }
}TEST CODE
public class MenuTest {
   public static void main(String[] args) throws OperationNotSupportedException {
       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);
       // 메뉴 항목을 추가하는 부분
       pancakeHouseMenu.add(new MenuItem("팬케이크","블루베리 팬케이크",true,2.99));
       dinerMenu.add(new MenuItem("파스타", "올리브 파스타",true, 3.89));
       dinerMenu.add(dessertMenu);
       dessertMenu.add(new MenuItem("애플 파이", "바닐라 아이스크림이 얹혀있는 애플 파이", true, 1.59));
       Waitress waitress = new Waitress(allMenus);
       waitress.printMenu();
   }
}Waitress (root node)
public class Waitress {
    MenuComponent allMenus;
    public Waitress(MenuComponent allMenus) {
        this.allMenus = allMenus;
    }
    public void printMenu() throws OperationNotSupportedException {
        allMenus.print();
    }
}- 모든 객체에 있는 메소드 정의 및 예외처리 -> 통합 관리
public abstract class MenuComponent {
    public void add(MenuComponent menuComponent) throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
    public void remove(MenuComponent menuComponent) throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
    public MenuComponent getChild(int i) throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
    public String getName() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public String getDescription() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public double getPrice() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public boolean isVegetarian() throws OperationNotSupportedException{
        throw new OperationNotSupportedException();
    }
    public void print() throws OperationNotSupportedException {
        throw new OperationNotSupportedException();
    }
}public class Menu extends MenuComponent{
    ArrayList<MenuComponent> menuComponents = new ArrayList<>();
    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);
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public String getDescription() {
        return description;
    }
    public void print() throws OperationNotSupportedException {
        System.out.print("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("---------------------");
        Iterator iterator = menuComponents.iterator();
        while (iterator.hasNext()) {
            MenuComponent menuComponent = (MenuComponent) iterator.next();
            menuComponent.print();
        }
    }
}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;
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public String getDescription() {
        return description;
    }
    @Override
    public boolean isVegetarian() {
        return vegetarian;
    }
    @Override
    public double getPrice() {
        return price;
    }
    public void print() {
        System.out.print("   " + getName());
        if (isVegetarian()) System.out.print(" (v)");
        System.out.println(", " + getPrice());
        System.out.println("      -- " + getDescription());
    }
}- Menu 및 MenuItem을 인터페이스를 사용해서 팩토리 메소드 방식으로 개선할 수 없을까??
Author And Source
이 문제에 관하여(디자인 패턴 - 컴포지트 패턴), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ahnseongeun/디자인-패턴-컴포지트-패턴저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)