迭代器模式

为什么会有迭代器模式

我们在对对象元素进行处理时,有时需要将同一类对象堆起来成为一个集合,集合的数据类型可以是数组、栈、列表、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) {...}@Overridepublic 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;elsereturn  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;elsereturn 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();}
}

迭代器类图

迭代器模式作用

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

设计模式_迭代器模式01相关推荐

  1. 【GOF23设计模式】迭代器模式

    [GOF23设计模式]迭代器模式 来源:http://www.bjsxt.com/  一.[GOF23设计模式]_迭代器模式.JDK内置迭代器.内部类迭代器 1 package com.test.it ...

  2. [转载] Python进阶:设计模式之迭代器模式

    参考链接: Python中的迭代器 在软件开发领域中,人们经常会用到这一个概念--"设计模式"(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一 ...

  3. 每日学一个设计模式1——迭代器模式

    引言 精通设计模式是从码农脱颖而出的条件之一.跟着<图解设计模式>这本书学习设计模式,从今天开始,一天总结一个设计模式. 迭代器模式(一个一个遍历) 用处 隐藏遍历集合的内部结构,遍历不同 ...

  4. php迭代器实例,php设计模式之迭代器模式实例分析【星际争霸游戏案例】

    本文实例讲述了php设计模式之迭代器模式.分享给大家供大家参考,具体如下: 星际的任务关一般会有这样的设定:一开始电脑的农民不采矿,如果战斗打响,或者玩家造出第一个兵,电脑的农民开始采矿. 我们自然会 ...

  5. java设计模式迭代器模式_迭代器模式和Java

    java设计模式迭代器模式 大家好,在本文中,我们将检查Iterator Pattern . 我知道你们中许多人已经使用过一种设计模式,但是也许您没有意识到它是模式,或者不知道它的巨大价值. 根据&l ...

  6. 设计模式之迭代器模式(Iterator)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  7. 设计模式复习-迭代器模式

    Iterator.H #pragma once #include <list> #include <windows.h> using namespace std;/* 设计模式 ...

  8. php foreach 循环 判断index 小于多少_PHP设计模式之迭代器模式 - 硬核项目经理

    一说到这个模式,就不得不提循环语句.在<大话设计模式>中,作者说道这个模式现在的学习意义更大于实际意义,这是为什么呢?当然就是被foreach这货给整得.任何语言都有这种类似的语法可以方便 ...

  9. Java 设计模式之迭代器模式

    一.了解迭代器模式 1.1 什么是迭代器模式 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 迭代器模式把游走的任务放在迭代器上,而不是聚合上.这样简化了聚合的接口和 ...

最新文章

  1. 理解什么是MyBatis?
  2. python globals().get,python – 为什么人们会使用globals()来定义变量
  3. 对MIME格式的邮件文件进行解码获取其可读内容和附件等
  4. 怎么优化GO语言服务的内存占用
  5. 53.连续分区分配vs分连续分区分配
  6. Leetcode 100. 相同的树 解题思路及C++实现
  7. Android --- 单一控件覆盖其他控件的方法
  8. bank should not have so many managers
  9. 自定义带进度条的WebView , 增加获取web标题和url 回掉
  10. php项目安装器,php服务器环境安装及项目搭建
  11. 一,彻底理解第一个C语言程序 Hello World
  12. dataset.xsd的定义(vs2008)
  13. Linux内存管理:内存描述之内存区域zone
  14. 【洛谷 P1772】 [ZJOI2006]物流运输(Spfa,dp)
  15. C# WPF框架从http协议上获取返回的json数据及其解析json数据
  16. 订阅号助手android,微信订阅号助手app
  17. 云计算体系结构中soa构建层_云计算架构分为哪几层 云计算具体学什么
  18. Chrome手势插件
  19. iOS 手势的用法
  20. JavaScript的继承,原型和原型链

热门文章

  1. HTML期末学生大作业-班级校园我的校园网页设计与实现html+css+javascript
  2. 关于AHB-RAM的一些内容1
  3. workers.properties配置详解
  4. 顶级程序员的心得 –– Coders at Work
  5. 24点卡牌游戏C++实现
  6. 微信支付(扫码支付)微信公众平台开发教程(6)
  7. vue常用的时间、手机号等的格式化方法
  8. 大话UWB技术之核心命脉:TDOA与TOF
  9. 【翻译】和麻美学姐一起的世界树(マミさんと世界樹スレ)第二话
  10. 德雷福斯(Dreyfus)技能获取模型