设计模式_06_迭代器模式

迭代器模式

为什么会有迭代器模式

我们在对对象元素进行处理时,有时需要将同一类对象堆起来成为一个集合,集合的数据类型可以是数组、栈、列表、HashMap等数据类型;但在某些时候,你的客户想要遍历这些对象,出于数据安全,你又不想让用户知道存储对象元素的集合的数据类型,迭代器的作用就是能让客户遍历你的对象,而又无法窥视你是如何(存储对象元素的集合数据类型客户不知道)存储对象的。

没有使用迭代器的代码设计

对象村餐厅和对象寸煎饼屋合并
餐厅对象和煎饼屋对象共用的菜单项类
public class MenuItem {

    String name;
    String description;
    double price;

    public MenuItem(String name, String description, double price) {
        this.name = name;
        this.description = description;
        this.price = price;
    }
    public String getName() {...}

    public void setName(String name) {...}

    public String getDescription() {...}

    public void setDescription(String description) {...}

    public double getPrice() {...}

    public void setPrice(double price) {...}

    @Override
    public String toString() {...}
}
餐厅菜单对象
//餐厅菜单实现
public class DinerMenu {
    int numberOfItems=0;
    MenuItem[] menuItems;
	static final int MAX_ITEMS=6;
    public DinerMenu(){
        menuItems = new MenuItem[MAX_ITEMS];
        addItem("BLT","Bacon with lettuce",2.99);
        addItem("Vegetarian BLT","Bacon with tomato",2.99);
        addItem("Hotdog","A hot dog,with sauerkraut",2.99);
    }

    public void addItem(String name,String description,Double price){
        MenuItem menuItem = new MenuItem(name,description,price);
        if(numberOfItems >= MAX_ITEMS){
            System.out.println("error");
        }else{
            menuItems[numberOfItems] = menuItem;
            numberOfItems++;
        }
    }

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

}
煎饼屋菜单对象
//煎饼屋菜单实现
public class PancakeHouseMenu {

    ArrayList<MenuItem> menuItems = new ArrayList<MenuItem>();;

    public PancakeHouseMenu() {
        addItem("A Pancake Breakfase","Pancakes whith eggs ang toast",2.99);
        addItem("A Pancake Breakfase","Pancakes whith eggs ang toast",2.99);
        addItem("A Pancake Breakfase","Pancakes whith eggs ang toast",2.99);
    }

    public void addItem(String name,String description,double price){
        MenuItem menuItem = new MenuItem(name, description, price);
        menuItems.add(menuItem);
    }
    public ArrayList<MenuItem> getMenuItems(){
        return menuItems;
    }
}

创建一个Java版本的女招待,女招待能按需为顾客打印定制的菜单

//女招待
public class Alice {

   void printMenu(){
       //获得煎饼屋菜单对象
       PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
       //获得煎饼屋对象中的菜单列表
       ArrayList<MenuItem> menuItems = pancakeHouseMenu.getMenuItems();

       //遍历菜单列表
       for(int i=0;i<menuItems.size();i++) {
           MenuItem menuItem = menuItems.get(i);
           System.out.println(menuItem.getName() + " ");
           System.out.println(menuItem.getDescription()+ " ");
           System.out.println(menuItem.getPrice()+ " ");
       }
       //获得餐厅菜单对象
       DinerMenu dinerMenu = new DinerMenu();
       //获得餐厅菜单对象中的菜单数组
       MenuItem[] menuItems1 = dinerMenu.getMenuItems();
       //遍历菜单数组
       for(int i=0;i<menuItems1.length;i++){
           MenuItem menuItem = menuItems1[i];
           System.out.println(menuItem.getName()+" ");
           System.out.println(menuItem.getDescription()+" ");
           System.out.println(menuItem.getPrice()+" ");
       }
   }
}

为了打印菜单我们需要遍历两个不同的集合。
在这里插入图片描述

使用了自定义迭代器的代码设计

迭代器接口

//迭代器接口
public interface Iterator {
    boolean hasNext();
    MenuItem next();
}

煎饼屋菜单列表迭代器

//煎饼屋菜单列表迭代器
public class PancakeHouseIterator implements Iterator {

    ArrayList<MenuItem> items;
    int count = 0;

    public PancakeHouseIterator(ArrayList<MenuItem> menuItems){
        this.items=menuItems;
    }

    public boolean hasNext(){
        if(count >= items.size() || items.get(count)==null)
            return false;
        else
            return  true;
    }

    public MenuItem next(){
        MenuItem menuItem = items.get(count);
        count++;
        return menuItem;
    }
}
//煎饼屋菜单实现
public class PancakeHouseMenu {

    ArrayList<MenuItem> menuItems = new ArrayList<MenuItem>();;

    public PancakeHouseMenu() {
        addItem("A Pancake Breakfase","Pancakes whith eggs ang toast",2.99);
        addItem("A Pancake Breakfase","Pancakes whith eggs ang toast",2.99);
        addItem("A Pancake Breakfase","Pancakes whith eggs ang toast",2.99);
    }

    public void addItem(String name,String description,double price){
        MenuItem menuItem = new MenuItem(name, description, price);
        menuItems.add(menuItem);
    }
    public Iterator createrIterator(){
      return new PancakeHouseIterator(menuItems);
    }
}

餐厅菜单迭代器

//餐厅菜单迭代器
public class DinerMenuIterator implements  Iterator{

    MenuItem[] menuItems;
    int position = 0;
    public DinerMenuIterator(MenuItem[] menuItems){
        menuItems = menuItems;
    }

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

    public MenuItem next(){
        MenuItem menuItem = menuItems[position];
        position++;
        return menuItem;
    }
}

//餐厅菜单实现
public class DinerMenu {
    int numberOfItems=0;
    MenuItem[] menuItems;

    public DinerMenu(){
        addItem("BLT","Bacon with lettuce",2.99);
        addItem("Vegetarian BLT","Bacon with tomato",2.99);
        addItem("Hotdog","A hot dog,with sauerkraut",2.99);
    }

    public void addItem(String name,String description,Double price){
        MenuItem menuItem = new MenuItem(name,description,price);
        menuItems[numberOfItems] = menuItem;
        numberOfItems++;
    }

    public Iterator createIterator(){
        return new DinerMenuIterator(menuItems);
    }
}
//使用迭代器的女招待
public class Alice {
	  PancakeHouseMenu pancakeHouseMenu;
   	  Iterator menuItems;
   void printMenu(){
       //获得煎饼屋菜单对象
       pancakeHouseMenu = new PancakeHouseMenu();
       //获得煎饼屋对象中的菜单迭代器
       menuItems = pancakeHouseMenu.createrIterator();

       //获得餐厅菜单对象
       DinerMenu dinerMenu = new DinerMenu();
       //获得餐厅菜单对象中的菜单迭代器
       Iterator menuItems1 = dinerMenu.createIterator();

   }
    
   void printMenu(Iterator iterator){
       while(iterator.hasNext()){
           MenuItem menuItem = iterator.next();
           System.out.println(menuItem.getName() + " ");
           System.out.println(menuItem.getDescription()+ " ");
           System.out.println(menuItem.getPrice()+ " ");
       }
   }
}

现在菜单的实现被封装,女招待不知道菜单如何持有菜单项的集合;只要实现迭代器,我们只需要一个循环,就可以多态的处理任何项的集合;由原先的捆绑道具体类(MenuITtem[]和ArrayList),到现在只需要使用一个Iterator接口,使程序变得更具维护和扩展。

唯一不足的是女招待仍然绑定到具体的菜单类(PancakeHouseMenu和DinerMenu).

在这里插入图片描述

使用Java提供的Iterator进行优化

为PancakeHouseMenu和DinerMenu提供应该公共接口Menu

public interface Menu {
    Iterator<MenuItem> createIterator();
}

PancakeHouseIterator和DinerIterator实现java提供的迭代器接口(不用在自定义Iterator)

public class PancakeHouseIterator implements Iterator {
	//内容不变
}

public class DinerMenuIterator implements Iterator {
	//内容不变
}

PancakeHouseMenu和DinerMenu

//煎饼屋菜单实现
public class PancakeHouseMenu implements Menu {
	//内容不变
  	
    //java自带的迭代器需要声明泛型
    public Iterator<MenuItem> createIterator(){
      return new PancakeHouseIterator(menuItems);
    }
}
//餐厅菜单实现
public class DinerMenu implements Menu {
	//内容不变
  	
    //java自带的迭代器需要声明泛型
    public Iterator<MenuItem> createIterator(){
        return new DinerMenuIterator(menuItems);
    }

}

Alice

//使用迭代器的女招待
public class Alice {

    Menu pancakeHouseMenu;
    Menu dinerMenu;

    public Alice(Menu pancakeHouseMenu,Menu dinerMenu){
        this.pancakeHouseMenu = pancakeHouseMenu;
        this.dinerMenu = dinerMenu;
    }
    void printMenu(){
       //获得煎饼屋菜单对象
       pancakeHouseMenu = new PancakeHouseMenu();
       //获得煎饼屋对象中的菜单迭代器
       Iterator menuItems = pancakeHouseMenu.createIterator();
       printMenu(menuItems);

       //获得餐厅菜单对象
       dinerMenu = new DinerMenu();
       //获得餐厅菜单对象中的菜单迭代器
       Iterator menuItems1 = dinerMenu.createIterator();
       printMenu(menuItems1);
   }
    void printMenu(Iterator<MenuItem> iterator){
        while(iterator.hasNext()){
            MenuItem menuItem = iterator.next();
            System.out.println(menuItem.getName() + " ");
            System.out.println(menuItem.getDescription()+ " ");
            System.out.println(menuItem.getPrice()+ " ");
        }
   }
}

测试

public class MenuTestDrive {
    public static void main(String[] args) {
        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
        DinerMenu dinerMenu = new DinerMenu();
        Alice alice = new Alice(pancakeHouseMenu,dinerMenu);
        alice.printMenu();

    }
}

迭代器类图
在这里插入图片描述

迭代器模式作用

迭代器模式让我们变了聚合元素,而不暴露器潜在实现;同时迭代器拿走了遍历元素的责任,把它交给迭代器对象而不是聚合对象,使得聚合对象的职责更加明确,使其专注于管理对象集合,简化了聚合的接口和实现

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值