设计模式分为三种类型,共23种

  1. 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式。
  2. 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
  3. 行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)。

创建型模式主要用于创建对象
结构型模式主要用于处理类或对象的组合
行为型模式主要用于描述类或对象如何交互和怎样分配职责

1、基本介绍

  1. 迭代器模式(Iterator Pattern)是常用的设计模式,属于行为型模式
  2. 如果我们的集合元素是用不同的方式实现的,有数组,还有java的集合类,
    或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历
    方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。
  3. 迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,
    不需要知道集合对象的底层表示,即:不暴露其内部的结构。

2、迭代器模式的注意事项和细节

优点

  1. 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以
    遍历对象了。
  2. 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚
    合的具体组成。
  3. 提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做单一责任
    原则)。在聚合类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集
    合的责任分开,这样一来集合改变的话,只影响到聚合对象。而如果遍历方式改变
    的话,只影响到了迭代器。
  4. 当要展示一组相似对象,或者遍历一组相同对象时使用, 适合使用迭代器模式

缺点

  1. 每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类

3、例子

餐厅和煎饼屋合并,现在想要煎饼屋菜单作为早餐的菜单,餐厅的菜单做午餐的菜单。但是两者有一个使用了ArrayList记录菜单,有一个使用了数组记录菜单,
菜单项

package designpattern.iterator.improve;public class MenuItem {String name;String description;boolean vegetarian;double price;//每个菜单都有名称,叙述,是否为素食的标志还有价格,这些值传递入构造器来初始化这个菜单项public MenuItem(String name, String description, boolean vegetarian, double price) {this.name = name;this.description = description;this.vegetarian = vegetarian;this.price = price;}public String getName() {return name;}public String getDescription() {return description;}public double getPrice() {return price;}public boolean isVegetarian() {return vegetarian;}
}

采用数组记录菜单的类

package designpattern.iterator.improve;import java.util.Iterator;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 sauerkraut, relish, onions, topped with cheese",false, 3.05);addItem("Steamed Veggies and Brown Rice","Steamed vegetables over brown rice", true, 3.99);addItem("Pasta","Spaghetti with Marinara Sauce, and a slice of sourdough bread",true, 3.89);}public void addItem(String name, String description, boolean vegetarian, double price) {MenuItem menuItem = new MenuItem(name, description, vegetarian, price);if (numberOfItems >= MAX_ITEMS) {System.err.println("Sorry, menu is full!  Can't add item to menu");} else {menuItems[numberOfItems] = menuItem;numberOfItems = numberOfItems + 1;}}public MenuItem[] getMenuItems() {return menuItems;}// other menu methods here(如果这里有新的方法,也是依赖于数组)
}

采用ArrayList记录菜单的类

package designpattern.iterator.improve;import java.util.ArrayList;
import java.util.Iterator;public class PancakeHouseMenu  {ArrayList<MenuItem> menuItems;public PancakeHouseMenu() {//      这里使用ArrayList存储菜单项menuItems = new ArrayList<MenuItem>();addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs and toast", true,2.99);addItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false,2.99);addItem("Blueberry Pancakes","Pancakes made with fresh blueberries and blueberry syrup",true,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){//      要加入一个菜单项,创建一个新的菜单项对象,传入每一个变量,然后将他加入ArrayList中MenuItem menuItem = new MenuItem(name, description, vegetarian, price);menuItems.add(menuItem);}public ArrayList<MenuItem> getMenuItems() {return menuItems;}// other menu methods here(这里如果有新的方法,那么也是依赖于ArrayList)
}

要想有个方法打印菜单项,那么上面有两个菜单使用不同的方式记录菜单,所有需要不同的方式遍历菜单,因此需要两个循环,如果还有第三家餐厅采用不同的实现出现,那么就得多加一个循环

这里的问题是不同对接会类型所造成的遍历需要多次,解决:创建一个对象,称为迭代器,利用他来封装‘’遍历集合内的每个对象的过程”

迭代器接口

package designpattern.iterator.improve;public interface Iterator {boolean hasNext();MenuItem next();
}

具体的迭代器–为餐厅菜单服务

package designpattern.iterator.improve;public class DinerMenuIterator implements Iterator {MenuItem[] items;int position = 0;//记录当前数据遍历的位置
// 构造器需要 传入一个菜单项的数组当做参数public DinerMenuIterator(MenuItem[] items) {this.items = items;}
//  next方法返回数组内的下一项,并递增其位置public MenuItem next() {/*MenuItem menuItem = items[position];position = position + 1;return menuItem;*/// or shorten to return items[position++];}public boolean hasNext() {/*if (position >= items.length || items[position] == null) {return false;} else {return true;}*/// or shorten toreturn items.length > position;}
}

具体的迭代器–煎饼屋菜单服务

package designpattern.iterator.improve;import java.util.ArrayList;
import java.util.List;public class PancakeHouseMenuIterator implements Iterator {List<MenuItem> items;int position = 0;//记录list的位置
//  构造器需要 传入一个菜单项的list当做参数public PancakeHouseMenuIterator(List<MenuItem> items) {this.items = items;}public MenuItem next() {/* MenuItem item = items.get(position);position = position + 1;return item;*/// or shorten to:return items.get(position++);}public boolean hasNext() {/*if (position >= items.size()) {return false;} else {return true;}*/// or shorten to:return items.size() > position;}
}

修改上面的两个餐厅菜单项

package designpattern.iterator.improve;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 sauerkraut, relish, onions, topped with cheese",false, 3.05);addItem("Steamed Veggies and Brown Rice","Steamed vegetables over brown rice", true, 3.99);addItem("Pasta","Spaghetti with Marinara Sauce, and a slice of sourdough bread",true, 3.89);}public void addItem(String name, String description, boolean vegetarian, double price) {MenuItem menuItem = new MenuItem(name, description, vegetarian, price);if (numberOfItems >= MAX_ITEMS) {System.err.println("Sorry, menu is full!  Can't add item to menu");} else {menuItems[numberOfItems] = menuItem;numberOfItems = numberOfItems + 1;}}//    public MenuItem[] getMenuItems() {//      return menuItems;
//  }public Iterator createIterator() {return  new DinerMenuIterator(menuItems);}// other menu methods here(如果这里有新的方法,也是依赖于数组)
}
package designpattern.iterator.improve;import java.util.ArrayList;public class PancakeHouseMenu  {ArrayList<MenuItem> menuItems;public PancakeHouseMenu() {//      这里使用ArrayList存储菜单项menuItems = new ArrayList<MenuItem>();addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs and toast", true,2.99);addItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false,2.99);addItem("Blueberry Pancakes","Pancakes made with fresh blueberries and blueberry syrup",true,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){//      要加入一个菜单项,创建一个新的菜单项对象,传入每一个变量,然后将他加入ArrayList中MenuItem menuItem = new MenuItem(name, description, vegetarian, price);menuItems.add(menuItem);}//   public ArrayList<MenuItem> getMenuItems() {//      return menuItems;
//  }public Iterator createIterator() {return  new PancakeHouseMenuIterator(menuItems);}// other menu methods here(这里如果有新的方法,那么也是依赖于ArrayList)
}

整合迭代器代码的类

package designpattern.iterator.improve;public class Waitress {PancakeHouseMenu 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");printMenu(dinerIterator);}private void printMenu(Iterator iterator) {while (iterator.hasNext()) {MenuItem menuItem = iterator.next();System.out.print(menuItem.getName() + ", ");System.out.print(menuItem.getPrice() + " -- ");System.out.println(menuItem.getDescription());}}//   其它的方法
}
/*
MENU
----
BREAKFAST
K&B's Pancake Breakfast, 2.99 -- Pancakes with scrambled eggs and toast
Regular Pancake Breakfast, 2.99 -- Pancakes with fried eggs, sausage
Blueberry Pancakes, 3.49 -- Pancakes made with fresh blueberries and blueberry syrup
Waffles, 3.59 -- Waffles with your choice of blueberries or strawberriesLUNCH
Vegetarian BLT, 2.99 -- (Fakin') Bacon with lettuce & tomato on whole wheat
BLT, 2.99 -- Bacon with lettuce & tomato on whole wheat
Soup of the day, 3.29 -- Soup of the day, with a side of potato salad
Hotdog, 3.05 -- A hot dog, with sauerkraut, relish, onions, topped with cheese
Steamed Veggies and Brown Rice, 3.99 -- Steamed vegetables over brown rice
Pasta, 3.89 -- Spaghetti with Marinara Sauce, and a slice of sourdough bread
*/

测试类

package designpattern.iterator.improve;public class MenuTestDrive {public static void main(String args[]) {PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();DinerMenu dinerMenu = new DinerMenu();Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);waitress.printMenu();}
}

好处:

  • 菜单的实现已经被封装起来了,Waitress类不知道菜单是如何存储器菜单项集合的;
  • 只要实现了迭代器,我们只需要一个循环,就可以多态地处理任何项的集合

缺点:

  • Waitress类中仍然捆绑了两个具体的菜单类

目前的设置:

  • 使用一个共同的迭代器接口,实现了两个具体的类。
  • 两个菜单都实现了一样的方法createIterator,但是没有实现相同接口,修改成实现相同的接口后,waitress就不会依赖于具体的菜单了。
  • 迭代器接口让waitess能够从具体类的实现中解耦。他不需要知道菜单是使用数组还是ArrayList,他只需要关心他能否拿到迭代器。
  • 还有我们目前是自定义一个迭代器接口,也可以直接使用java中的Iterator接口。

添加一个menu接口,两个菜单项都实现他

package designpattern.iterator.improve;public interface Menu {public Iterator createIterator();
}

修改Waitress代码

如果要添加新的餐厅过来的时候,可添加具体的菜单迭代器 实现迭代器接口,添加新的菜单项类,然后在Waitress中加入

设计模式--迭代器模式相关推荐

  1. java设计模式迭代器模式_迭代器设计模式示例

    java设计模式迭代器模式 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式 ...

  2. java设计模式迭代器模式_Java中的迭代器设计模式–示例教程

    java设计模式迭代器模式 迭代器模式是一种行为模式,它用于提供遍历一组对象的标准方式. Iterator模式在Java Collection Framework中得到了广泛使用,其中Iterator ...

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

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

  4. java设计模式迭代器模式_Java中的迭代器设计模式

    java设计模式迭代器模式 Iterator design pattern in one of the behavioral pattern. Iterator pattern is used to ...

  5. 23种设计模式-迭代器模式《三国名将》

    对于许久不用的东西,容易忘记.百度许久,也未能找到自己所要. 从今日起,有些东西就记载下来,不仅方便自己,希望能帮到他人吧! 定义 提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部 ...

  6. [Head First设计模式]生活中学设计模式——迭代器模式

    系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 [Head First设计模式]山西面馆中的设计模式--观察者模式 [Head First设计模式]山西面馆中的设计模式- ...

  7. Java设计模式——迭代器模式

    概述 网上大部分人说迭代模式的时候,总是以某一种可遍历的对象为例进行介绍.这是可行的,这也是迭代模式的基本原型.当我看到<Head Frist设计模式>中迭代模式的时候,感觉要是能从另一个 ...

  8. C++设计模式-迭代器模式

    目录 基本概念 代码与实例 基本概念 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 当你需要一个聚集对象,而且不管这些对象,而不管这些对象是 ...

  9. 解读设计模式----迭代器模式(Iterator Pattern),谁才是迭代高手

    一.你在开发中使用过迭代吗?      当你在使用JavaScript开发客户端应用的时候使用过for...in吗?  1<script type="text/javascript&q ...

  10. JAVA 设计模式 迭代器模式

    用途 迭代器模式 (Iterator) 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 迭代器模式是一种行为型模式. 结构 图-迭代器模式结构图 Iterator : 定义访 ...

最新文章

  1. 查看无线网卡工作模式
  2. 安全管家安卓_pc-cillin和腾讯电脑管家比较哪个更好
  3. 关闭iOS软键盘的小方法
  4. java log4j logback jcl_Java 日志二三事
  5. java socket 线程池_java socket编程的一个例子(线程池)
  6. 接口实例(C#,IShape)【C#】
  7. linux工作笔记-linux之间文件传输图形界面工具gftp
  8. SpringBoot之创建SpringBoot项目(idea开发)
  9. 人口、人口密度分析项目-条形图
  10. 科大讯飞2017年报:营收54亿利润5.9亿,政府补助1.18亿
  11. [转载] windows下python包的导入方法
  12. 机器学习基础算法17-决策树-鸢尾花数据集分类及决策树深度与过拟合
  13. 影视.20190507
  14. cocos2d-x学习笔记10:动作3:补间动作
  15. C#中IntPtr类型
  16. 消息轰炸(python)
  17. 3d模型计算机教室,大学教室3d模型
  18. 《Linux命令行与shell脚本编程大全(第3版)》读书笔记
  19. 中国工商银行网上银行B2C在线支付接口说明
  20. python-requests 模拟登陆京东

热门文章

  1. 华为手机怎么使用分屏_这是一份华为手机必备小技巧使用说明
  2. 微信小程序中实现获奖名单滚动播放
  3. 如何使用Java制作网课搜题软件?我来教你,so easy
  4. oracle,通过plsql创建用户表空间和所属用户示例
  5. win10.10 激活
  6. 生鲜配送分拣管理系统哪家比较强?
  7. iOS-image图片旋转方向
  8. 苹果手机里的照片导入电脑
  9. 根据一段时间区间,按月份拆分成多个时间段
  10. NDN全栈: 一、命名数据网络(Named Data Networking)背景介绍