1. 程式人生 > >設計模式之迭代器與組合模式(四)

設計模式之迭代器與組合模式(四)

因為這系列篇幅較長,所以在這裡也不進行任何鋪墊,直奔主題去啦。

利用組合設計選單

我們要如何在選單上應用組合模式呢?一開始,我們需要建立一個元件介面來作為選單和選單項的共同介面,讓我們能夠用統一的做法來處理選單和選單項。換句話說,我們可以針對選單或選單項呼叫相同的方法。

讓我們從頭來看看如何讓選單能夠符合組合模式的結構:

實現選單元件

好了,我們開始編寫選單元件的抽象類;請記住,選單元件的角色是為葉節點和組合節點提供一個共同的介面。

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 abstract Iterator<MenuComponent> createIterator();
 
    public void print() {
        throw new UnsupportedOperationException();
    }
}

讓我們來看選單類。別忘了,這是組合類圖裡的葉類,它實現組合內元素的行為。

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 Iterator<MenuComponent> createIterator() {
        return new NullIterator();
    }
 
    public void print() {
        System.out.print("  " + getName());
        if (isVegetarian()) {
            System.out.print("(v)");
        }
        System.out.println(", " + getPrice());
        System.out.println("     -- " + getDescription());
    }

}

我們已經有了選單項,還需要組合類,這就是我們叫做選單的。別忘了,此組合類可以持有選單項或其他選單。

public class Menu extends MenuComponent {
    Iterator<MenuComponent> iterator = null;
    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 Iterator<MenuComponent> createIterator() {
        if (iterator == null) {
            iterator = new CompositeIterator(menuComponents.iterator());
        }
        return iterator;
    }
 
 
    public void print() {
        System.out.print("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("---------------------");
    }
}

因為選單是一個組合,包含了選單項和其他的選單,所以它的print()應該打印出它所包含的一切。如果它不這麼做,我們就必須遍歷整個組合的每個節點,然後將每一項打印出來。這麼一來,也就失去了使用組合結構的意義。

所以,print還得進行優化,如下:

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();
    }
}

看到上面了沒,我們用了迭代器。用它遍歷所有選單元件,遍歷過程中,可能遇到其他選單,或者是遇到選單項。由於選單和選單項都實現了print,那我們只要呼叫print即可。

開始測試資料之前,我們瞭解一下,在執行時選單組合是什麼樣的:

開始執行我們的測試程式啦:

public class MenuTestDrive {
    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 combined");
  
        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, and blueberry syrup",
            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",
            "A bowl of the 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(
            "Steamed Veggies and Brown Rice",
            "A medly of steamed vegetables over brown rice", 
            true, 
            3.99));
 
        dinerMenu.add(new MenuItem(
            "Pasta",
            "Spaghetti with Marinara Sauce, and a slice of sourdough bread",
            true, 
            3.89));
   
        dinerMenu.add(dessertMenu);
  
        dessertMenu.add(new MenuItem(
            "Apple Pie",
            "Apple pie with a flakey crust, topped with vanilla icecream",
            true,
            1.59));
        dessertMenu.add(new MenuItem(
            "Cheesecake",
            "Creamy New York cheesecake, with a chocolate graham crust",
            true,
            1.99));
        dessertMenu.add(new MenuItem(
            "Sorbet",
            "A scoop of raspberry and a scoop of lime",
            true,
            1.89));

        cafeMenu.add(new MenuItem(
            "Veggie Burger and Air Fries",
            "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
            true, 
            3.99));
        cafeMenu.add(new MenuItem(
            "Soup of the day",
            "A cup of the soup of the day, with a side salad",
            false, 
            3.69));
        cafeMenu.add(new MenuItem(
            "Burrito",
            "A large burrito, with whole pinto beans, salsa, guacamole",
            true, 
            4.29));
 
        Waitress waitress = new Waitress(allMenus);
   
        waitress.printVegetarianMenu();
 
    }
}

結果這裡就不附上了,請大家自行去跑程式碼實現吧。相信你們又對組合模式也已經有了一個大概了吧。下一篇,還有更犀利的,組合迭代器等著我們。小編馬上回去搞起來,安排上。

愛生活,愛學習,愛感悟,愛挨踢

相關推薦

設計模式組合模式

很高興,這本書總共13章,這次已經是到第9章了;同時也很遺憾,小編脫離了書本,還是不知道如何描述一個設計模式。就比如迭代器與組合模式,原書篇幅比較長,小編儘量通俗易懂些,不到之處,還請各位小夥伴參考原書,小編也歡迎和大家一起交流。 有許多種方法可以把物件堆起來成為一個集合(collection)。你可以把它們

設計模式組合模式

在上次的文章中,我們通過層層引導,已經知道了迭代器模式的由來。現在我們再好好總結下。 關於迭代器模式,你所需要知道的第一件事情,就是它依賴於一個名為迭代器的介面。這是一個可能的迭代器的介面: 現在,我們一旦有了這個介面,就可以為各種物件集合實現迭代器:陣列、列表、散列表...如果我麼想要為陣列實現迭代器,

設計模式組合模式

現在我們已經能愉快地看著一頁一頁羅列出來的選單進行點菜了。現在又有的小夥伴希望能夠加上一份餐後甜點的“子選單”。怎麼辦呢?我們不僅僅要支援多個選單,甚至還要支援選單中的選單。 如果我們能讓甜點選單變成餐廳選單集合的一個元素,那該有多好。但是根據現在的實現,根本做不到呀。我們想要的是這樣的: 我們需要什麼

設計模式組合模式

因為這系列篇幅較長,所以在這裡也不進行任何鋪墊,直奔主題去啦。 利用組合設計選單 我們要如何在選單上應用組合模式呢?一開始,我們需要建立一個元件介面來作為選單和選單項的共同介面,讓我們能夠用統一的做法來處理選單和選單項。換句話說,我們可以針對選單或選單項呼叫相同的方法。 讓我們從頭來看看如何讓選單能夠符合組合

設計模式組合模式(java)

這是我看Head first設計模式書籍之後想要總結的知識點,一方面是對自己學習的東西總結和提煉加強自己的理解和記憶,另一方面是給大家簡化這本書,方便大家快速瞭解各種設計模式。 我想提醒大家的是,設計模式只是前人總結的一些經驗套路,實際上還是要在開發專案中慢慢體會,不可成為

HeadFirst 設計模式 9組合模式餐廳合併

迭代器模式 提供一種方法順序訪問一個聚合物件中的各個元素,而又不暴露其內部的表示。 迭代器模式讓我們能夠遊走於聚合內的每個元素,而又不暴露其內部的表示。把遊走的任務放在迭代器上,而不是聚合上。這樣簡化了聚合的介面和實現,也讓責任各得其所。 集合collection/聚合ag

設計模式組合模式

迭代器與組合模式 定義  迭代器模式提供一種方法順序訪問一個聚合物件中的各個元素,而又不暴露其內部的表示。 組合模式允許你將物件組合成樹形結構來表現“整體/部分”層次結構。組合能讓客戶以一致的方式處理個別對象以及物件組合 例子  廢話不多說,先看具體案例

走進設計模式的世界9:我們的公司很複雜-組合模式

迭代器模式 : 提供一個方法順序訪問一個聚合物件中的各個元素,而又不暴露其內部表示。 組合模式 : 允許你將物件組成樹形結構來表現“整體/部分”的層次結構。組合能讓可以以一致的方式處理個別對象和物件組合。 設計原則:類應該只有一個改變的理由 解釋 : 迭代器允許訪問聚合的元素

組合模式轉載

程式碼實在太多了,偷個懶轉載大佬的 https://www.cnblogs.com/lzhp/p/3427704.html 迭代器模式 提供了一種方法順序訪問一個聚合物件中的各個元素,而又不暴露內部的表示 把在元素之間遍歷的責任交給迭代器,而不是聚合物件 角色

9.組合模式

Head-First-Design-Patterns-master\src\headfirst\designpatterns\iterator Head-First-Design-Patterns-master\src\headfirst\designpatterns\co

設計模式的藝術 行為型模式模式

前言 現在的電視機都配置了一個遙控器,使用者可以通過遙控器去選擇上一個或者下一個臺,我們只需要知道如何使用這個遙控器,而無須關注電視是怎麼把電視訊道放入其中的,在軟體實際的開發中,也有這麼一種類,它儲存著多個成員物件,這些類通常稱為聚合類,對應的物件稱為聚合物件。為了方便操作這些聚合物件,同時可

研磨設計模式業務場景

場景描述 專案客戶方收購了一家小公司,這家小公司有自己的工資系統,客戶方的工資系統內部採用List來記錄工資列表,新收購的小公司的工資系統內部採用陣列來記錄工資列表,整合兩個系統的工資表資料 已有系統程式碼示例 一個統一了的工資描述模型 /**

研磨設計模式

聚合 指一組物件的組合結構,如Java中的集合、陣列等 迭代器模式 提供一種方法,順序訪問一個聚合物件中的各個元素,而又不需要暴露該物件的內部表示 目標 以一個統一的方式來訪問內部實現不同的聚合物件 示例程式碼

設計模式模式Iterator

前言: 參考圖書:軟體設計模式與體系結構 參考部落格:https://www.cnblogs.com/wanson/articles/9277813.html   正題:         迭代器(iterator)有時又稱遊標

golang設計模式模式

迭代器模式 定義 wiki: 在 物件導向程式設計裡,迭代器模式是一種設計模式,是一種最簡單也最常見的設計模式。它可以讓使用者透過特定的介面巡訪容器中的每一個元素而不用瞭解底層的實作。 簡單點說,為一個容器設定一個迭代函式,可以使用這個迭代函式來順序訪問其中的每一個元素,而外部無需知道底層實現

java設計模式

本文介紹行為型模式的一種模式——迭代器模式。該模式主要用於對某一物件集合進行遍歷,將物件的資料儲存和遍歷進行分離。在Java語言中有著較高的應用頻率。 1、定義:提供一種方法順序地訪問一個聚合物件中的各個元素而不需要暴露該物件的內部表示。 2、模式結構: (1)Iter

23種設計模式模式

迭代器模式的定義 定義: 它提供一種方法訪問一個容器物件中各個元素, 而又不需暴露該物件的內部細節 其類圖如下:   其中角色: Iterator 抽象迭代器: 抽象迭代器負責定義訪問和遍歷元素的介面, 而且基本上是有固定的三個方法: first()獲得第一個元素, n

Android設計模式模式

迭代器模式又稱遊標模式, 是行為型設計模式之一。迭代器模式源於對容器的訪問,比如Java中的List、Map、陣列等。 對容器物件的訪問必然會涉及到遍歷演算法,可以將遍歷演算法封裝在容器中,或者不提供遍歷演算法。如果將遍歷演算法封裝在容器中,那麼容器類就承擔了過多的功能,容器類不僅要維護自身內部

Python進階:設計模式模式

  在軟體開發領域中,人們經常會用到這一個概念——“設計模式”(design pattern),它是一種針對軟體設計的共性問題而提出的解決方案。在一本聖經級的書籍《設計模式:可複用面向物件軟體的基礎》(1991年,Design Patterns - Elements of Reusable Obj

設計模式模式Iterator Pattern

這篇部落格,我們要詳細講解的是迭代器模式(Iterator Pattern),將要講解的內容有:迭代器模式 的定義,作用,詳細設計分析等方面。 一、Pattern name 迭代器模式(Iterator Pattern) : 提供一種方法