设计模式 —— 迭代器模式(Iterator Pattern)
来源:互联网 发布:jordan淘宝官方旗舰店 编辑:程序博客网 时间:2024/05/16 00:38
迭代器模式(Iterator Pattern)
概念:
定义:迭代器模式 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
迭代器模式是一种简单常见的设计模式,在我们使用编程语言中的集合容器都会有迭代器。
组成:
Aggregate(抽象聚合):共同的接口供所有的聚合使用。
ConcreteAggregate(聚合):持有一个对象的集合,并实现 createIterator 方法,返回集合的迭代器。
Iterator(抽象迭代器接口):包含所有迭代器都必须实现的方法。
ConcreteIterator(具体迭代器):实现了迭代器接口的具体迭代器。
例子:
现有两家超市,一家为水果超市,一家为零食超市。他们分别请了两位编程人员帮他们实现打印品种清单程序。结果第一家编程人员用数组集合来存储不同的水果,第二家编程人员用 ArrayList 集合来存储零食种类。如下:
物品类:
public class Item { private String name; private String description; double price; public Item(String name, String description, double price) { this.name = name; this.description = description; this.price = price; } public String getName() { return name; } public String getDescription() { return description; } public double getPrice() { return price; }}
水果超市类:
public class FruitSupermarket { ArrayList menuItems; public FruitSupermarket() { menuItems = new ArrayList(); //添加水果 addItem("苹果", "红色的", 1.99); addItem("香蕉", "黄色的", 2.00); addItem("橙子", "横色的", 3.12); } public void addItem(String name, String description, double price) { Item item = new Item(name, description, price); menuItems.add(item); } public ArrayList getMenuItems() { return menuItems; }}
零食超市类:
public class SnacksSupermarket { static final int MAX_ITEMS = 6; int numberOfItems = 0; Item[] menuItems; public SnacksSupermarket() { menuItems = new Item[MAX_ITEMS]; //添加零食 addItem("牛奶", "伊利", 2.24); addItem("糖", "阿尔卑斯", 5.12); addItem("巧克力", "金蒂", 1.23); } public void addItem(String name, String description, double price) { Item item = new Item(name, description, price); if (numberOfItems >= MAX_ITEMS) { System.out.println("抱歉,清单已满..."); } else { menuItems[numberOfItems] = item; numberOfItems += 1; } } public Item[] getMenuItems() { return menuItems; }}
现在假设两家超市合并了,我们要遍历两家超市的清单。
public class Supermarket { FruitSupermarket fruitSupermarket; SnacksSupermarket snacksSupermarket; public Supermarket() { fruitSupermarket = new FruitSupermarket(); snacksSupermarket = new SnacksSupermarket(); } //遍历菜单方法,内部分别包含两家超市的遍历。 public void printMenu() { ArrayList fruitItems = fruitSupermarket.getMenuItems(); Item[] snacksItems = snacksSupermarket.getMenuItems(); //遍历水果超市 System.out.println("fruitItem:"); for (int i = 0; i < fruitItems.size(); ++i) { Item item = (Item) fruitItems.get(i); System.out.print("name:" + item.getName()); System.out.print(" description:" + item.getDescription()); System.out.println(" price:" + item.getPrice()); } //遍历零食超市 System.out.println("\nsnacksItem:"); for (int i = 0; i < snacksSupermarket.getNumberOfItems(); ++i) { Item item = snacksItems[i]; System.out.print("name:" + item.getName()); System.out.print(" description:" + item.getDescription()); System.out.println(" price:" + item.getPrice()); } } public static void main(String[] args) { Supermarket supermarket = new Supermarket(); supermarket.printMenu(); }}
如果将来再次合并超市又必须修改代码,增加一个循环,我们可以发现上述代码成了 面向实现 编程而不是 面向接口。
我们来通过 迭代器模式 改进这个类。
先将两个超市类增加 createIterator() 方法,返回内部集合的迭代器。
由于 ArrayList 本身有迭代器,我们直接返回即可。
//省略原本类的方法 public Iterator createIterator() { return menuItems.iterator(); }
但零食超市中的数组集合没有迭代器,我们自己实现一个。
//Java 提供了迭代器接口,我们直接实现即可public class SnacksIterator implements Iterator { Item[] menuItems; int position = 0; public SnacksIterator(Item[] menuItems) { this.menuItems = menuItems; } //判断是否有下一个元素方法 public boolean hasNext() { if (position >= menuItems.length || menuItems[position] == null) { return false; }else { return true; } } //返回下一个对象方法 public Object next() { Item menuitem = menuItems[position]; position += 1; return menuitem; }}
//...省略原本类和方法 public Iterator createIterator() { return new SnacksIterator(menuItems); }
超市类:
public class Supermarket { FruitSupermarket fruitSupermarket; SnacksSupermarket snacksSupermarket; public Supermarket() { fruitSupermarket = new FruitSupermarket(); snacksSupermarket = new SnacksSupermarket(); } //由于实现了统一的接口,再次添加我们继续创建对应的迭代器类,加入 printMenu 即可。 public void printMenu() { //我们也可以将所有的清单加入集合中,这样下面的代码也不用改变了。 Iterator fruitIterator = fruitSupermarket.createIterator(); Iterator snacksIterator = snacksSupermarket.createIterator(); System.out.println("FruitSupermarket"); printMenu(fruitIterator); System.out.println("\nSnacksSupermarket"); printMenu(snacksIterator); } private void printMenu(Iterator iterator) { while (iterator.hasNext()) { Item item = (Item) iterator.next(); System.out.print("name:" + item.getName()); System.out.print(" description:" + item.getDescription()); System.out.println(" price:" + item.getPrice()); } } public static void main(String[] args) { Supermarket supermarket = new Supermarket(); supermarket.printMenu(); }}
适用场景:
- 访问一个聚合对象的内容而无需暴露它的内部表示。
- 需要为聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)
补充:设计原则
单一设计原则:一个类应该只有一个引起变化的原因
我们应该避免类内的改变,因为修改代码很容易造成许多潜在的错误。如果一个类具有两个改变的原因,那么类变化的几率就很大了,并且当它真的改变时,我们的设计中会有两方面受到影响。当一个模块或一个类被设计成只支持一组相关的功能时,我们说它具有高内聚。反之,当被设计成支持一组不相关的功能时,我们说它具有低内聚。
- 设计模式(16)——迭代器模式(Iterator Pattern)
- 设计模式 —— 迭代器模式(Iterator Pattern)
- Java设计模式——迭代器模式(Iterator Pattern)
- 设计模式——迭代器模式(Iterator Pattern)
- Java设计模式——迭代器模式(Iterator Pattern)
- 【设计模式】迭代器模式(Iterator Pattern)
- java设计模式——迭代器模式(Iterator Pattern)
- 设计模式学习—迭代器模式(Iterator Design Pattern)
- 设计模式之-迭代器(Iterator pattern)
- Iterator Pattern--迭代器设计模式
- 我所理解的设计模式(C++实现)——迭代器模式(Iterator Pattern)
- 我所理解的设计模式(C++实现)——迭代器模式(Iterator Pattern)
- 我所理解的设计模式(C++实现)——迭代器模式(Iterator Pattern)
- 设计模式21:Iterator Pattern (迭代器模式)
- 设计模式-迭代器模式(Iterator Pattern)
- c++设计模式:迭代器模式(Iterator Pattern)
- 设计模式 - 迭代器模式(iterator pattern) 详解
- 设计模式-迭代器模式(iterator pattern)
- SSM之Service层基于注解的声明式事物
- HDU 5212 Code【莫比乌斯反演】
- MySQL常用命令行操作大全
- 基于Ubuntu14.04+ROS indigo环境LSD-SLAM的数据集测试成功
- 290. Word Pattern(技巧:记录当前位置来判断两个字符串是否符合)
- 设计模式 —— 迭代器模式(Iterator Pattern)
- 常用的Linux命令
- 一往无前,请记住最初的梦想。
- 【LeetCode】101. Symmetric Tree 解题报告
- CSS中link与import的区别
- dp-挑战程序设计竞赛-状态的选择 多重部分和 LIS
- Struts2上课笔记
- ASCII、Unicode、GBK和UTF-8字符编码
- 我的第六次上机作业