• 设计模式 4 —— 迭代器和组合模式(组合)


    设计模式目录:

    设计模式 1 ——观察者模式

    设计模式 2 —— 装饰者模式 

    设计模式 3 —— 迭代器和组合模式(迭代器)

    设计模式 4 —— 迭代器和组合模式(组合)

    设计模式 5 —— 工厂模式

    设计模式 6 —— 单件模式

    设计模式 7 —— 命令模式

    设计模式 8 —— 适配器和外观模式

    设计模式 9 —— 模板方法模式

    设计模式 10 —— 状态模式

    参考

    概述:

    第1部分 问题引入以及定义

    第2部分 实现代码

    第3部分 用组合来使用迭代器

    第1部分 问题引入以及定义

    先来看下符合我们需求的结构图:

    组合模式允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象的组合。

    下面看看让菜单能够符合组合模式的结构:

    第2部分 代码实现

    好了,下面开始编写菜单组合件的抽象类,请记住,菜单组合件的角色是为叶节点和组合节点提供一个共同的接口。

     1 package firsthead.composite;
     2 
     3 /**
     4  * 菜单组件
     5  * @ClassName: MenuComponent
     6  * 
     7  * @author Xingle
     8  * @date 2014-8-4 下午2:50:19
     9  */
    10 public abstract class MenuComponent {
    11     
    12     /*因为有些方法只对菜单项有意义,而有些则只对菜单有意义,默认实现是抛出UnsupportedOperationException异常。
    13      * 这样,如果菜单项或者菜单不支持某个操作,他们就不需要做任何事情,直接继承默认实现就可以了。*/
    14     
    15     //组合的方法组织在一起,即新增、删除和取得菜单组件
    16     public void add(MenuComponent menuComponent){
    17         throw new UnsupportedOperationException();
    18     }
    19     
    20     public MenuComponent getChild(int i){
    21         throw new UnsupportedOperationException();
    22     }
    23     
    24     public void remove(MenuComponent menuComponent) {
    25         throw new UnsupportedOperationException();
    26     }
    27     
    28     //下面是操作的方法
    29     public String getName(){
    30         throw new UnsupportedOperationException();
    31     }
    32 
    33     public String getDescription() {
    34         throw new UnsupportedOperationException();
    35     }
    36     public double getPrice() {
    37         throw new UnsupportedOperationException();
    38     }
    39     public boolean isVegetarian() {
    40         throw new UnsupportedOperationException();
    41     }
    42     
    43     public void print() {
    44         throw new UnsupportedOperationException();
    45     }
    46 }

    实现菜单项:

     1 package firsthead.composite;
     2 
     3 /**
     4  * 菜单项
     5  * @ClassName: MenuItem
     6  * TODO
     7  * @author Xingle
     8  * @date 2014-8-4 下午2:57:20
     9  */
    10 public class MenuItem extends MenuComponent{
    11     String name;
    12     String description;
    13     boolean vegetarian;
    14     double price;
    15     
    16     public MenuItem(String name, String description, boolean vegetarian, double price){
    17         this.name = name;
    18         this.description = description;
    19         this.vegetarian = vegetarian;
    20         this.price = price;
    21     }
    22 
    23     public String getName() {
    24         return name;
    25     }
    26 
    27     public String getDescription() {
    28         return description;
    29     }
    30 
    31     public boolean isVegetarian() {
    32         return vegetarian;
    33     }
    34 
    35     public double getPrice() {
    36         return price;
    37     }
    38 
    39     public void print(){
    40         System.out.println(" "+getName());
    41         if(isVegetarian()){
    42             System.out.print("(v)");
    43         }
    44         System.out.println(", "+getPrice());
    45         System.out.println("     -- " + getDescription());
    46     }
    47 
    48 }

    实现组合菜单:

     1 package firsthead.composite;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 
     6 /**
     7  * 菜单
     8  * @ClassName: Menu
     9  * TODO
    10  * @author Xingle
    11  * @date 2014-8-4 下午3:02:15
    12  */
    13 public class Menu extends MenuComponent{
    14     //菜单可以有任意数目的孩子,这些孩子都必须属于MenuComponent类型,我们使用内部的ArrayList记录它们
    15     ArrayList menuComponents = new ArrayList();
    16     String name;
    17     String description;
    18     
    19     public Menu(String name,String description){
    20         this.name = name;
    21         this.description = description;
    22     }
    23     
    24     //将菜单项和其他菜单加入菜单中,同理,处理删除或者取得某个MenuComponent
    25     public void add(MenuComponent menuComponent){
    26         menuComponents.add(menuComponent);
    27     }
    28     
    29     public void remove(MenuComponent menuComponent){
    30         menuComponents.remove(menuComponent);
    31     }
    32     
    33     public MenuComponent getChild(int i){
    34         return (MenuComponent) menuComponents.get(i);
    35     }
    36     
    37     public String getName() {
    38         return name;
    39     }
    40  
    41     public String getDescription() {
    42         return description;
    43     }
    44     
    45     //注意,这里没有覆盖getPrice()或者isVegetarian(),因为这些方法对Menu来说并没有意义
    46     
    47     public void print(){
    48         System.out.print("
    " + getName());
    49         System.out.println(", " + getDescription());
    50         System.out.println("---------------------");
    51         
    52         //不仅打印出菜单本身的信息,也打印出菜单内所有组件的内容:其他菜单和菜单项
    53         Iterator iterator = menuComponents.iterator();
    54         while(iterator.hasNext()){
    55             MenuComponent menuComponent = (MenuComponent)iterator.next();
    56             menuComponent.print();
    57         }
    58     }
    59 }

    女招待代码:

     1 package firsthead.composite;
     2 
     3 /**
     4  * 女招待
     5  * @ClassName: Waitress
     6  * TODO
     7  * @author Xingle
     8  * @date 2014-8-4 下午3:18:33
     9  */
    10 public class Waitress {
    11     MenuComponent allMenus;
    12     
    13     //只要将最顶层的菜单组件交给女招待就可以了
    14     public Waitress(MenuComponent allMenus){
    15         this.allMenus = allMenus;
    16     }
    17     
    18     public void print(){
    19         allMenus.print();
    20     }
    21 
    22 }

    测试程序:

     1 package firsthead.composite;
     2 
     3 /**
     4  * 组合模式测试程序
     5  * 
     6  * @ClassName: MenuTestDrive TODO
     7  * @author Xingle
     8  * @date 2014-8-4 下午3:22:43
     9  */
    10 public class MenuTestDrive {
    11 
    12     public static void main(String[] args) {
    13         MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU",
    14                 "早餐 Breakfast");
    15         MenuComponent dinerMenu = new Menu("DINER MENU", "午餐 Lunch");
    16         MenuComponent cafeMenu = new Menu("CAFE MENU", "晚餐 Dinner");
    17         MenuComponent dessertMenu = new Menu("DESSERT MENU",
    18                 " Dessert of course!");
    19         MenuComponent coffeeMenu = new Menu("COFFEE MENU",
    20                 "Stuff to go with your afternoon coffee");
    21 
    22         // 最顶层菜单
    23         MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
    24 
    25         // 将每个菜单加入allMenus中
    26         allMenus.add(pancakeHouseMenu);
    27         allMenus.add(dinerMenu);
    28         allMenus.add(cafeMenu);
    29 
    30         // pancakeHouseMenu 加入具体菜单项
    31         pancakeHouseMenu.add(new MenuItem("K&B's Pancake Breakfast",
    32                 "Pancakes with scrambled eggs, and toast", true, 2.99));
    33         pancakeHouseMenu.add(new MenuItem("Regular Pancake Breakfast",
    34                 "Pancakes with fried eggs, sausage", false, 2.99));
    35         pancakeHouseMenu.add(new MenuItem("Blueberry Pancakes",
    36                 "Pancakes made with fresh blueberries, and blueberry syrup",
    37                 true, 3.49));
    38         pancakeHouseMenu.add(new MenuItem("Waffles",
    39                 "Waffles, with your choice of blueberries or strawberries",
    40                 true, 3.59));
    41 
    42         //dinerMenu 加入具体菜单项
    43         dinerMenu.add(new MenuItem("Vegetarian BLT",
    44                 "(Fakin') Bacon with lettuce & tomato on whole wheat", true,
    45                 2.99));
    46         dinerMenu.add(new MenuItem("BLT",
    47                 "Bacon with lettuce & tomato on whole wheat", false, 2.99));
    48 
    49         // 
    50         dinerMenu.add(dessertMenu);
    51 
    52         dessertMenu.add(new MenuItem("Apple Pie",
    53                 "Apple pie with a flakey crust, topped with vanilla icecream",
    54                 true, 1.59));
    55 
    56         dessertMenu.add(new MenuItem("Cheesecake",
    57                 "Creamy New York cheesecake, with a chocolate graham crust",
    58                 true, 1.99));
    59         dessertMenu.add(new MenuItem("Sorbet",
    60                 "A scoop of raspberry and a scoop of lime", true, 1.89));
    61         
    62         //cafeMenu 加入具体菜单项
    63         cafeMenu.add(new MenuItem(
    64                 "Veggie Burger and Air Fries",
    65                 "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
    66                 true, 3.99));
    67         cafeMenu.add(new MenuItem("Soup of the day",
    68                 "A cup of the soup of the day, with a side salad", false, 3.69));
    69 
    70         cafeMenu.add(coffeeMenu);
    71 
    72         coffeeMenu
    73                 .add(new MenuItem(
    74                         "Veggie Burger and Air Fries",
    75                         "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
    76                         true, 3.99));
    77         coffeeMenu.add(new MenuItem("Bagel",
    78                 "Flavors include sesame, poppyseed, cinnamon raisin, pumpkin",
    79                 false, 0.69));
    80         
    81         Waitress waitress = new Waitress(allMenus);
    82         waitress.print();
    83     }
    84 
    85 }

    执行结果:


    ALL MENUS, All menus combined
    ---------------------

    PANCAKE HOUSE MENU, 早餐 Breakfast
    ---------------------
    K&B's Pancake Breakfast
    (v), 2.99
    -- Pancakes with scrambled eggs, and toast
    Regular Pancake Breakfast
    , 2.99
    -- Pancakes with fried eggs, sausage
    Blueberry Pancakes
    (v), 3.49
    -- Pancakes made with fresh blueberries, and blueberry syrup
    Waffles
    (v), 3.59
    -- Waffles, with your choice of blueberries or strawberries

    DINER MENU, 午餐 Lunch
    ---------------------
    Vegetarian BLT
    (v), 2.99
    -- (Fakin') Bacon with lettuce & tomato on whole wheat
    BLT
    , 2.99
    -- Bacon with lettuce & tomato on whole wheat

    DESSERT MENU, Dessert of course!
    ---------------------
    Apple Pie
    (v), 1.59
    -- Apple pie with a flakey crust, topped with vanilla icecream
    Cheesecake
    (v), 1.99
    -- Creamy New York cheesecake, with a chocolate graham crust
    Sorbet
    (v), 1.89
    -- A scoop of raspberry and a scoop of lime

    CAFE MENU, 晚餐 Dinner
    ---------------------
    Veggie Burger and Air Fries
    (v), 3.99
    -- Veggie burger on a whole wheat bun, lettuce, tomato, and fries
    Soup of the day
    , 3.69
    -- A cup of the soup of the day, with a side salad

    COFFEE MENU, Stuff to go with your afternoon coffee
    ---------------------
    Veggie Burger and Air Fries
    (v), 3.99
    -- Veggie burger on a whole wheat bun, lettuce, tomato, and fries
    Bagel
    , 0.69
    -- Flavors include sesame, poppyseed, cinnamon raisin, pumpkin

    第3部分 用组合来使用迭代器

    想要实现一个组合迭代器,我们为每个组件都加上createIterator()方法。先从抽象的MenuComponent类开始。

     1 package firsthead.composite;
     2 
     3 import java.util.Iterator;
     4 
     5 /**
     6  * 菜单组件
     7  * @ClassName: MenuComponent
     8  * 
     9  * @author Xingle
    10  * @date 2014-8-4 下午2:50:19
    11  */
    12 public abstract class MenuComponent {
    13     
    14     /*因为有些方法只对菜单项有意义,而有些则只对菜单有意义,默认实现是抛出UnsupportedOperationException异常。
    15      * 这样,如果菜单项或者菜单不支持某个操作,他们就不需要做任何事情,直接继承默认实现就可以了。*/
    16     
    17     //组合的方法组织在一起,即新增、删除和取得菜单组件
    18     public void add(MenuComponent menuComponent){
    19         throw new UnsupportedOperationException();
    20     }
    21     
    22     public MenuComponent getChild(int i){
    23         throw new UnsupportedOperationException();
    24     }
    25     
    26     public void remove(MenuComponent menuComponent) {
    27         throw new UnsupportedOperationException();
    28     }
    29     
    30     //下面是操作的方法
    31     public String getName(){
    32         throw new UnsupportedOperationException();
    33     }
    34 
    35     public String getDescription() {
    36         throw new UnsupportedOperationException();
    37     }
    38     public double getPrice() {
    39         throw new UnsupportedOperationException();
    40     }
    41     public boolean isVegetarian() {
    42         throw new UnsupportedOperationException();
    43     }
    44     
    45     public void print() {
    46         throw new UnsupportedOperationException();
    47     }
    48     
    49     //加入一个方法,每个菜单和菜单项都必须实现这个方法,即,对每一个组合调用createIterator()方法,将会应用于该组合的所有孩子
    50     public abstract Iterator createIterator();
    51 }

    修改菜单项和菜单组件的代码:

     1 package firsthead.composite;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 
     6 /**
     7  * 菜单
     8  * @ClassName: Menu
     9  * TODO
    10  * @author Xingle
    11  * @date 2014-8-4 下午3:02:15
    12  */
    13 public class Menu extends MenuComponent{
    14     //菜单可以有任意数目的孩子,这些孩子都必须属于MenuComponent类型,我们使用内部的ArrayList记录它们
    15     ArrayList menuComponents = new ArrayList();
    16     String name;
    17     String description;
    18     
    19     public Menu(String name,String description){
    20         this.name = name;
    21         this.description = description;
    22     }
    23     
    24     //将菜单项和其他菜单加入菜单中,同理,处理删除或者取得某个MenuComponent
    25     public void add(MenuComponent menuComponent){
    26         menuComponents.add(menuComponent);
    27     }
    28     
    29     public void remove(MenuComponent menuComponent){
    30         menuComponents.remove(menuComponent);
    31     }
    32     
    33     public MenuComponent getChild(int i){
    34         return (MenuComponent) menuComponents.get(i);
    35     }
    36     
    37     public String getName() {
    38         return name;
    39     }
    40  
    41     public String getDescription() {
    42         return description;
    43     }
    44     
    45     //注意,这里没有覆盖getPrice()或者isVegetarian(),因为这些方法对Menu来说并没有意义
    46     
    47     public void print(){
    48         System.out.print("
    " + getName());
    49         System.out.println(", " + getDescription());
    50         System.out.println("---------------------");
    51         
    52         //不仅打印出菜单本身的信息,也打印出菜单内所有组件的内容:其他菜单和菜单项
    53         Iterator iterator = menuComponents.iterator();
    54         while(iterator.hasNext()){
    55             MenuComponent menuComponent = (MenuComponent)iterator.next();
    56             menuComponent.print();
    57         }
    58     }
    59 
    60     /**
    61      * 
    62      * @Description: 
    63      * @return
    64      * @author xingle
    65      * @data 2014-8-4 下午4:39:12
    66      */
    67     @Override
    68     public Iterator createIterator() {
    69         //组合迭代器
    70         return new CompositeIterator(menuComponents.iterator());
    71     }
    72 }
     1 package firsthead.composite;
     2 
     3 import java.util.Iterator;
     4 
     5 /**
     6  * 菜单项
     7  * @ClassName: MenuItem
     8  * TODO
     9  * @author Xingle
    10  * @date 2014-8-4 下午2:57:20
    11  */
    12 public class MenuItem extends MenuComponent{
    13     String name;
    14     String description;
    15     boolean vegetarian;
    16     double price;
    17     
    18     public MenuItem(String name, String description, boolean vegetarian, double price){
    19         this.name = name;
    20         this.description = description;
    21         this.vegetarian = vegetarian;
    22         this.price = price;
    23     }
    24 
    25     public String getName() {
    26         return name;
    27     }
    28 
    29     public String getDescription() {
    30         return description;
    31     }
    32 
    33     public boolean isVegetarian() {
    34         return vegetarian;
    35     }
    36 
    37     public double getPrice() {
    38         return price;
    39     }
    40 
    41     public void print(){
    42         System.out.println(" "+getName());
    43         if(isVegetarian()){
    44             System.out.print("(v)");
    45         }
    46         System.out.println(", "+getPrice());
    47         System.out.println("     -- " + getDescription());
    48     }
    49 
    50     /**
    51      * 
    52      * @Description: TODO
    53      * @return
    54      * @author xingle
    55      * @data 2014-8-4 下午4:39:17
    56      */
    57     @Override
    58     public Iterator createIterator() {
    59         return new NullIterator();
    60     }
    61 
    62 }

    其中,菜单的组合迭代器代码,这部分代码多研读:

     1 package firsthead.composite;
     2 
     3 import java.util.Iterator;
     4 import java.util.Stack;
     5 
     6 /**
     7  * 组合迭代器
     8  * @ClassName: CompositeIterator
     9  * TODO
    10  * @author Xingle
    11  * @date 2014-8-4 下午4:41:49
    12  */
    13 public class CompositeIterator implements Iterator{
    14     
    15     Stack stack = new Stack();
    16     
    17     //将要遍历的顶层组合的迭代器传入,放入一个堆栈数据结构中
    18     public CompositeIterator(Iterator iterator){
    19         stack.push(iterator);
    20     }
    21 
    22     /**
    23      * 
    24      * @Description: TODO
    25      * @return
    26      * @author xingle
    27      * @data 2014-8-4 下午4:42:46
    28      */
    29     @Override
    30     public boolean hasNext() {
    31         //检查堆栈是否被清空,如果已经空了,就表示没有下一元素了
    32         if(stack.empty()){
    33             return false;
    34         }
    35         else{
    36             //否则,从堆栈的顶层中取出迭代器,看看是否还有下一元素。如果它没有元素,将它弹出堆栈,然后递归地调用hasNext()。
    37             Iterator Iterator = (java.util.Iterator) stack.peek();
    38             if(!Iterator.hasNext()){
    39                 stack.pop();
    40                 return hasNext();
    41             }else{
    42                 return true;
    43             }
    44         }
    45     }
    46 
    47     /**
    48      * 
    49      * @Description: TODO
    50      * @return
    51      * @author xingle
    52      * @data 2014-8-4 下午4:42:46
    53      */
    54     @Override
    55     public Object next() {
    56         //当客户想要取得下一个元素的时候,先调用hasNext()来确定是否还有下一个
    57         if(hasNext()){
    58             //如果还有下一个元素,就从堆栈中取出目前的迭代器,然后取得它的下一个元素
    59             Iterator iterator = (Iterator) stack.peek();            
    60             MenuComponent component = (MenuComponent) iterator.next();
    61             //如果元素是一个菜单,就有了另一个需要被包含进遍历的组合,放进堆栈中。 不管是不是菜单,都返回该组件。
    62             if(component instanceof Menu){
    63                 stack.push(component.createIterator());
    64             }
    65             return component;
    66         }else {
    67             return null;
    68         }
    69     }
    70 
    71     /**
    72      * 不支持删除,这里只有遍历
    73      * @Description: TODO
    74      * @author xingle
    75      * @data 2014-8-4 下午4:42:46
    76      */
    77     @Override
    78     public void remove() {
    79         throw new UnsupportedOperationException();
    80         
    81     }
    82 
    83 }

    菜单组件的NullIterator,空迭代器,指项目内没有可以遍历的:

     1 package firsthead.composite;
     2 
     3 import java.util.Iterator;
     4 
     5 /**
     6  * 空迭代器
     7  * @ClassName: NullIterator
     8  * 
     9  * @author Xingle
    10  * @date 2014-8-4 下午5:05:25
    11  */
    12 public class NullIterator implements Iterator{
    13 
    14     /**
    15      * 
    16      * @Description: TODO
    17      * @return
    18      * @author xingle
    19      * @data 2014-8-4 下午5:05:47
    20      */
    21     @Override
    22     public boolean hasNext() {
    23         return false;
    24     }
    25 
    26     /**
    27      * 
    28      * @Description: TODO
    29      * @return
    30      * @author xingle
    31      * @data 2014-8-4 下午5:05:47
    32      */
    33     @Override
    34     public Object next() {
    35         return null;
    36     }
    37 
    38     /**
    39      * 
    40      * @Description: TODO
    41      * @author xingle
    42      * @data 2014-8-4 下午5:05:47
    43      */
    44     @Override
    45     public void remove() {
    46         throw new UnsupportedOperationException();
    47         
    48     }
    49 
    50 }

    女招待,增加打印蔬菜的方法printVegetarianMenu():

     1 package firsthead.composite;
     2 
     3 import java.util.Iterator;
     4 
     5 /**
     6  * 女招待
     7  * @ClassName: Waitress
     8  * TODO
     9  * @author Xingle
    10  * @date 2014-8-4 下午3:18:33
    11  */
    12 public class Waitress {
    13     MenuComponent allMenus;
    14     
    15     //只要将最顶层的菜单组件交给女招待就可以了
    16     public Waitress(MenuComponent allMenus){
    17         this.allMenus = allMenus;
    18     }
    19     
    20     public void print(){
    21         allMenus.print();
    22     }
    23     
    24     public void printVegetarianMenu(){
    25         Iterator iterator = allMenus.createIterator();
    26         while(iterator.hasNext()){
    27             MenuComponent menucomponent = (MenuComponent) iterator.next();
    28             try{//调用全部的menucomponent的isVegetarian()方法,但是Menu会抛出异常,因为它们不支持这个操作
    29                 if(menucomponent.isVegetarian()){
    30                     menucomponent.print();
    31                 }
    32             }catch(UnsupportedOperationException e){
    33             }
    34             
    35         }
    36     }
    37 
    38 }

    测试程序:

     1 package firsthead.composite;
     2 
     3 /**
     4  * 组合模式测试程序
     5  * 
     6  * @ClassName: MenuTestDrive 
     7  * @author Xingle
     8  * @date 2014-8-4 下午3:22:43
     9  */
    10 public class MenuTestDrive {
    11 
    12     public static void main(String[] args) {
    13         MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU",
    14                 "早餐 Breakfast");
    15         MenuComponent dinerMenu = new Menu("DINER MENU", "午餐 Lunch");
    16         MenuComponent cafeMenu = new Menu("CAFE MENU", "晚餐 Dinner");
    17         MenuComponent dessertMenu = new Menu("DESSERT MENU",
    18                 " Dessert of course!");
    19         MenuComponent coffeeMenu = new Menu("COFFEE MENU",
    20                 "Stuff to go with your afternoon coffee");
    21 
    22         // 最顶层菜单
    23         MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
    24 
    25         // 将每个菜单加入allMenus中
    26         allMenus.add(pancakeHouseMenu);
    27         allMenus.add(dinerMenu);
    28         allMenus.add(cafeMenu);
    29 
    30         // pancakeHouseMenu 加入具体菜单项
    31         pancakeHouseMenu.add(new MenuItem("K&B's Pancake Breakfast",
    32                 "Pancakes with scrambled eggs, and toast", true, 2.99));
    33         pancakeHouseMenu.add(new MenuItem("Regular Pancake Breakfast",
    34                 "Pancakes with fried eggs, sausage", false, 2.99));
    35         pancakeHouseMenu.add(new MenuItem("Blueberry Pancakes",
    36                 "Pancakes made with fresh blueberries, and blueberry syrup",
    37                 true, 3.49));
    38         pancakeHouseMenu.add(new MenuItem("Waffles",
    39                 "Waffles, with your choice of blueberries or strawberries",
    40                 true, 3.59));
    41 
    42         //dinerMenu 加入具体菜单项
    43         dinerMenu.add(new MenuItem("Vegetarian BLT",
    44                 "(Fakin') Bacon with lettuce & tomato on whole wheat", true,
    45                 2.99));
    46         dinerMenu.add(new MenuItem("BLT",
    47                 "Bacon with lettuce & tomato on whole wheat", false, 2.99));
    48 
    49         // 
    50         dinerMenu.add(dessertMenu);
    51 
    52         dessertMenu.add(new MenuItem("Apple Pie",
    53                 "Apple pie with a flakey crust, topped with vanilla icecream",
    54                 true, 1.59));
    55 
    56         dessertMenu.add(new MenuItem("Cheesecake",
    57                 "Creamy New York cheesecake, with a chocolate graham crust",
    58                 true, 1.99));
    59         dessertMenu.add(new MenuItem("Sorbet",
    60                 "A scoop of raspberry and a scoop of lime", true, 1.89));
    61         
    62         //cafeMenu 加入具体菜单项
    63         cafeMenu.add(new MenuItem(
    64                 "Veggie Burger and Air Fries",
    65                 "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
    66                 true, 3.99));
    67         cafeMenu.add(new MenuItem("Soup of the day",
    68                 "A cup of the soup of the day, with a side salad", false, 3.69));
    69 
    70         cafeMenu.add(coffeeMenu);
    71 
    72         coffeeMenu
    73                 .add(new MenuItem(
    74                         "Veggie Burger and Air Fries",
    75                         "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
    76                         true, 3.99));
    77         coffeeMenu.add(new MenuItem("Bagel",
    78                 "Flavors include sesame, poppyseed, cinnamon raisin, pumpkin",
    79                 false, 0.69));
    80         
    81         Waitress waitress = new Waitress(allMenus);
    82         //waitress.print();
    83         waitress.printVegetarianMenu();
    84     }
    85 
    86 }

    执行结果:

    K&B's Pancake Breakfast
    (v), 2.99
    -- Pancakes with scrambled eggs, and toast
    Blueberry Pancakes
    (v), 3.49
    -- Pancakes made with fresh blueberries, and blueberry syrup
    Waffles
    (v), 3.59
    -- Waffles, with your choice of blueberries or strawberries
    Vegetarian BLT
    (v), 2.99
    -- (Fakin') Bacon with lettuce & tomato on whole wheat
    Apple Pie
    (v), 1.59
    -- Apple pie with a flakey crust, topped with vanilla icecream
    Cheesecake
    (v), 1.99
    -- Creamy New York cheesecake, with a chocolate graham crust
    Sorbet
    (v), 1.89
    -- A scoop of raspberry and a scoop of lime
    Apple Pie
    (v), 1.59
    -- Apple pie with a flakey crust, topped with vanilla icecream
    Cheesecake
    (v), 1.99
    -- Creamy New York cheesecake, with a chocolate graham crust
    Sorbet
    (v), 1.89
    -- A scoop of raspberry and a scoop of lime
    Veggie Burger and Air Fries
    (v), 3.99
    -- Veggie burger on a whole wheat bun, lettuce, tomato, and fries
    Veggie Burger and Air Fries
    (v), 3.99
    -- Veggie burger on a whole wheat bun, lettuce, tomato, and fries
    Veggie Burger and Air Fries
    (v), 3.99
    -- Veggie burger on a whole wheat bun, lettuce, tomato, and fries

      看下女招待打印蔬菜菜单的方法中,一般来说,try/catch是一种错误处理的方法,而不是程序逻辑的方法。如果不这么做,还有哪些选择呢?我们可以在调用isVegetarian()方法之前,用instanceof来检查菜单组件的运行类型,以确定它是菜单项。但是这么做,我们就会因为无法统一菜单和菜单项而失去透明性。

    我们也可以改写Menu的isVegetarian()方法,让它返回false,这提供了一个简单的解决方案,同时也保持了透明性。

      我们的解决方案是为了要清楚的表示我们的想法。我们真正想要传达的是:isVegetarian()是Menu没有支持的操作(这和说isVegetarian()是false意义不等同)。这样的做法也允许以后去为Menu实现一个合理的isVegetarian()方法,而我们不必为此再修改这里的代码了。


    参考:

    1. [Head First设计模式]生活中学设计模式——组合模式

  • 相关阅读:
    C# 5.0 in a Nutshell 读书笔记(一) 野峰
    CLR via C# 4th Edition 野峰
    杰佛里给 Windows Server 2019 Automation with PowerShell 一书所写序言 野峰
    .NET的跨平台调用一例(PreserveSig) 野峰
    Http请求响应
    为什么不要追随新的linux发行版
    make: *** [out/host/linuxx86/obj/STATIC_LIBRARIES/libgtest_host_intermediates/gtestall.o] Error change
    linux 下at&t语法的汇编之hello world!!
    android 编译错误001_cm9 for onda elite vi10
    把vim当作16进制编辑器使用、、
  • 原文地址:https://www.cnblogs.com/xingele0917/p/3890070.html
Copyright © 2020-2023  润新知