zoukankan      html  css  js  c++  java
  • 设计模式 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设计模式]生活中学设计模式——组合模式

  • 相关阅读:
    PHP调用WCF提供的方法
    关于git报 warning: LF will be replaced by CRLF in README.md.的警告的解决办法
    vue中引入mui报Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them的错误
    微信小程序报Cannot read property 'setData' of undefined的错误
    Vue那些事儿之用visual stuido code编写vue报的错误Elements in iteration expect to have 'v-bind:key' directives.
    关于xampp中无法启动mysql,Attempting to start MySQL service...的解决办法!!
    PHP的环境搭建
    新手PHP连接MySQL数据库出问题(Warning: mysqli_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES))
    手机号码、获得当前时间,下拉框,填写限制
    团队作业(五):冲刺总结
  • 原文地址:https://www.cnblogs.com/xingele0917/p/3890070.html
Copyright © 2011-2022 走看看