设计模式--迭代器模式
设计模式分为三种类型,共23种
- 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式。
- 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
- 行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)。
创建型模式主要用于创建对象
结构型模式主要用于处理类或对象的组合
行为型模式主要用于描述类或对象如何交互和怎样分配职责
1、基本介绍
- 迭代器模式(Iterator Pattern)是常用的设计模式,属于行为型模式
- 如果我们的集合元素是用不同的方式实现的,有数组,还有java的集合类,
或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历
方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。 - 迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,
不需要知道集合对象的底层表示,即:不暴露其内部的结构。
2、迭代器模式的注意事项和细节
优点
- 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以
遍历对象了。 - 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚
合的具体组成。 - 提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做单一责任
原则)。在聚合类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集
合的责任分开,这样一来集合改变的话,只影响到聚合对象。而如果遍历方式改变
的话,只影响到了迭代器。 - 当要展示一组相似对象,或者遍历一组相同对象时使用, 适合使用迭代器模式
缺点
- 每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类
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中加入
设计模式--迭代器模式相关推荐
- java设计模式迭代器模式_迭代器设计模式示例
java设计模式迭代器模式 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式 ...
- java设计模式迭代器模式_Java中的迭代器设计模式–示例教程
java设计模式迭代器模式 迭代器模式是一种行为模式,它用于提供遍历一组对象的标准方式. Iterator模式在Java Collection Framework中得到了广泛使用,其中Iterator ...
- java设计模式迭代器模式_迭代器模式和Java
java设计模式迭代器模式 大家好,在本文中,我们将检查Iterator Pattern . 我知道你们中许多人已经使用过一种设计模式,但是也许您没有意识到它是模式,或者不知道它的巨大价值. 根据&l ...
- java设计模式迭代器模式_Java中的迭代器设计模式
java设计模式迭代器模式 Iterator design pattern in one of the behavioral pattern. Iterator pattern is used to ...
- 23种设计模式-迭代器模式《三国名将》
对于许久不用的东西,容易忘记.百度许久,也未能找到自己所要. 从今日起,有些东西就记载下来,不仅方便自己,希望能帮到他人吧! 定义 提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部 ...
- [Head First设计模式]生活中学设计模式——迭代器模式
系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 [Head First设计模式]山西面馆中的设计模式--观察者模式 [Head First设计模式]山西面馆中的设计模式- ...
- Java设计模式——迭代器模式
概述 网上大部分人说迭代模式的时候,总是以某一种可遍历的对象为例进行介绍.这是可行的,这也是迭代模式的基本原型.当我看到<Head Frist设计模式>中迭代模式的时候,感觉要是能从另一个 ...
- C++设计模式-迭代器模式
目录 基本概念 代码与实例 基本概念 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 当你需要一个聚集对象,而且不管这些对象,而不管这些对象是 ...
- 解读设计模式----迭代器模式(Iterator Pattern),谁才是迭代高手
一.你在开发中使用过迭代吗? 当你在使用JavaScript开发客户端应用的时候使用过for...in吗? 1<script type="text/javascript&q ...
- JAVA 设计模式 迭代器模式
用途 迭代器模式 (Iterator) 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 迭代器模式是一种行为型模式. 结构 图-迭代器模式结构图 Iterator : 定义访 ...
最新文章
- 查看无线网卡工作模式
- 安全管家安卓_pc-cillin和腾讯电脑管家比较哪个更好
- 关闭iOS软键盘的小方法
- java log4j logback jcl_Java 日志二三事
- java socket 线程池_java socket编程的一个例子(线程池)
- 接口实例(C#,IShape)【C#】
- linux工作笔记-linux之间文件传输图形界面工具gftp
- SpringBoot之创建SpringBoot项目(idea开发)
- 人口、人口密度分析项目-条形图
- 科大讯飞2017年报:营收54亿利润5.9亿,政府补助1.18亿
- [转载] windows下python包的导入方法
- 机器学习基础算法17-决策树-鸢尾花数据集分类及决策树深度与过拟合
- 影视.20190507
- cocos2d-x学习笔记10:动作3:补间动作
- C#中IntPtr类型
- 消息轰炸(python)
- 3d模型计算机教室,大学教室3d模型
- 《Linux命令行与shell脚本编程大全(第3版)》读书笔记
- 中国工商银行网上银行B2C在线支付接口说明
- python-requests 模拟登陆京东