設計モード-複合モード


ふくごうパターン


  • 定義#テイギ#
  • オブジェクトは、ツリー構造として組織することができ、全体および部分が階層のパターン
  • となる.

  • 使用理由と特性
  • オブジェクトを収集し、すべて同じ方法で使用します.これは、クライアントのシンプル化に役立ちます:
  • 法では、構造全体の繰り返し動作によく用いられる.

  • に道を教える
  • 実際の応用UML
  • 古いコード

  • ディレクトリ構造
  • 従来のコードの問題
  • 新しいメニューを追加すると、Waitessクラスの作成者と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();
        }
    }
  • Menu Componentの追加
  • すべてのオブジェクトのメソッド定義と例外処理->統合管理
  • 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を使用して工場方法を改善できますか?