Head First 设计模式之迭代模式与组合模式之总结

迭代模式与组合模式要点:

      1.迭代器允许访问聚合的元素,而不需要暴露它的内部结构

      2.迭代器将遍历聚合的工作封装进一个对象中

      3.当使用迭代器的时候,我们一来聚合提供遍历

      4.迭代器提供了一个通用的接口,让我们遍历聚合的项时,就可以使用多态机制

      5.我们应该努力让一个类只分配一个责任

      6.组合模式提供一个结构,可同时包容个别对象和组合对象

      7.组合模式允许客户对个别对象以及组合对象一视同仁

      8.组合结构内的任意对象称为组件,组件可以使组合,也可以是叶子节点

      9.在实现组合模式时,有许多设计上的折衷。你要根据需要平衡透明性和安全性

 

 

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

 

好处:

  1. 支持以不同的方式遍历一个容器角色。根据实现方式的不同,效果上会有差别
  2. 简化了容器的接口。但是在java Collection中为了提高可扩展性,容器还是提供了遍历的接口
  3. 对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的

 

由此也能得出迭代器模式的适用范围:
  1. 访问一个容器对象的内容而无需暴露它的内部表示
  2. 支持对容器对象的多种遍历

  3. 为遍历不同的容器结构提供一个统一的接口(多态迭代)

 

意义:这个模式给你提供了一种方法,可以顺序访问一个聚集对象中的元素,而又不用知道内部是如何表示的。在设计中使用迭代器的影响是明显的:如果你有一个统一的方法访问聚合中的每一个对象,你就可以编写多态的代码和这些聚合搭配,使用---如同前面的printMenu()方法一样,只要有了迭代器这个方法根本不管菜单项究竟是由数组还是有ArrayList来保存。另一个对设计造成重要影响的,是迭代器模式把在元素之间游走的责任交给迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注它所应该专注的事情上面来。

 

餐厅的菜单:

public class MenuItem{
          String name;
          String description;
          boolean vegetarian;
          double price;

          public MenuItem(String name,String description,boolean vegetarian,doublic price){
                  this.name = name;
                  this.description = description;
                  this.vegetarian = vegetarian;
                  this.price;
          }

          public String getName(){
                  return name;
           }

           public String getDescription(){
                  return description;
           }

           public double getPrice(){
                  return price;
           }

           public boolean isVegetarian(){
                   return vegetarian;
           }
}

 
存在两个餐厅,存储餐单内容方式不同,有用ArrayList的,有用数组的,现在利用迭代器模式将这两个餐厅合并。

 

餐厅一:

public class PancakeHouseMenu{
         ArrayList menuItems;

         public PancakeHouseMenu()}{
                 menuItems = new ArrayList();
  
                 addItem("K&B's Pancake Breakfast","Pancakes with scrambled eggs,and toast",true,2.99);

                 addItem("Regular Pancake Breadfast","Pancakes with fried eggs,sausage",false ,2.99);

                 addItem("Blueberry Pancakes","Pancakes made with fresh blueberries",ture,3.49);

                 addItem("Waffles","Waffles,with your choice of blueberries or strawberries",true,3.59);
         }

         public void addItem(String name ,String description,boolean vegetarian,double price){
         MenuItem menuItem = new MenuItem(name,description ,vegetarian,price);
         menuItems.add(menuItem);

         public ArrayList getMenuItem(){
                  return menuItem;
         }
}
}

 

 餐厅二:

public class DinerMenu{
          static final int MAX_ITEMS = 6;
          int numberOfItems = 0;
          MenuItem[] menuItems;

         public DinerMenu(){
                   menuItems = new MenuItem[MAX_ITEMS];

                   addItem("Vegetarian BLT","(Fakin') Bacon with lettuce & tomato on whole wheat",true,2.99);

                   addItem("BLT","Bacon with lettuce & tomato on whole wheat",false,2.99);

                   addItem("Soup of the day","Soup of the day, with a side of potato salad",false,3.29);

                   addItem("Hotdog","a hot dog,with saurkraut ,relish,onions,topped with cheese",false,3.05);
         }
 
         public void addItem(String name,String description ,boolean vegetarian,price){
                   MenuItem menuItem = new MenuItem(name,description,vegetarian,price);

                   if(nuberOfItems >= MAX_ITEMS ){
                             System.out.println("Sorry ,menu is full! Can't add item to menu")}else{
                             menuItems[numberOfItems] = menuItem;
                             menuOfItems = numberOfItems +1;
                   }
         }

         public MenuItem[] getMenuItems(){
                   return menuItems;
         }
}

 

现在我们创建一个对象,将它称之为迭代器,利用它来封装“遍历集合内的每个对象的过程”

 

Iterator iterator = breakfastMenu.createIterator();

while(iterator.hasNext()){
          MenuItem menuItem = (MenuItem)iterator.next();
}

 

 现在我们需要实现一个具体的迭代器,为餐厅餐单服务:

 

public class DinerMenuIterator implements Iterator{
          MenuItem[] items;
          int position=0;

          public DinerMenuIterator(MenuItem[] items){
                    this.items = items;
          }

          public Object next(){
                    MenuItem menuItem = items[position];
                    position = position +1;
                    return menuItem;
          }

          public boolean hasNext(){
                    if(position >= items.length || items[position] == null){
                                return false;
                    }else{
                                 return true;
                    }
          }
}

 

此时还要修改餐厅菜单:

public class DinerMenu{
          static final int MAX_ITEMS = 6;
          int numberOfItems = 0;
          MenuItem[] menuItems;
          public DinerMenu(){
                   menuItems = new MenuItem[MAX_ITEMS];

                   addItem("Vegetarian BLT","(Fakin') Bacon with lettuce & tomato on whole wheat",true,2.99);

                   addItem("BLT","Bacon with lettuce & tomato on whole wheat",false,2.99);

                   addItem("Soup of the day","Soup of the day, with a side of potato salad",false,3.29);

                   addItem("Hotdog","a hot dog,with saurkraut ,relish,onions,topped with cheese",false,3.05);
         }

          public Iterator createIterator(){
                     return new DinerMenuIterator(menuItems);
          }

}

 

 

女招待员代码:

public class Waitress{

          PancakeHouseMean PancakeHouseMenu;
          DinerMenu dinerMenu;

          public Waitress(PancakeHouseMenu pancakeHouseMenu,DinerMenu dinerMenu){
          this.pancakeHouseMenu = pancakeHouseMenu;
          this.dinerMenu = dinerMenu;
          }

          public void printMenu(){
                    Iterator pancakeIterator = pancakeHouseMenu.createIterator();
                    Iterator dinerIterator = dinerMenu.createIterator();
                    System.out.println("Menu\n---\nBREAKFAST");
                    PrintMenu(pancakeIterator);
                    System.out.println("\nLUNCH");
                    printlnMenu(dinerIterator);
          }

          private void printMenu(Iterator iterator){
                      while(iterator.hasnext()){
                                MenuItem menuIterm = (MenuItem)iterator.next();
                                System.out.println(menuItem.getName()+", ");
                                System.out.println(menuItem.getPrice()+"--");
                                System.out.println(menuItem.getDecrisption());
                      }
          }
}

 

注意:Hashtable对于迭代器的支持是间接地,这个迭代器不是直接从Hashtable取出,而是由Hashtable的value取出的。Hashtable内部存储了两组对象:key和value。如果我们想要遍历value,当然是要先从Hashtable取得value,然后再取得迭代器。

 

 

组合模式:允许你讲对象组成属性结构。组合能让客户以一致的方式处理个别对象和对象组合。

 

1.组合模式让我们能用树形方式创建对象的结构,树里面包含了组合以及个别的对象

2.使用组合结构,我们能把相同的操作应用在组合和个别对象上。换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别。

 

单一责任原则:一个类应该只有一个引起变化的原因。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值