目录
Iterator 迭代器模式
目录
[TOC]
1. 概述
1.1. Head First设计模式定义
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露其内部的表示。
把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。
1.2. 自我理解
面向Iterator接口编程,无论底层的数据结构和迭代算法如何变化,调用者都不用修改代码
1.3. 迭代器的组成
迭代器(Iterator):迭代器定义访问和遍历元素的接口。
具体迭代器(ConcreteIterator):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置。
聚合(Aggregate):聚合定义创建相应迭代器对象的接口。
具体聚合(ConcreteAggregate):具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator 的一个适当的实例。
1.4. 迭代器模式适用场景
访问一个聚合对象的内容而无需暴露它的内部表示。
支持对聚合对象的多种遍历。
为遍历不同的聚合结构提供一个统一的接口。
2. UML
3. Example
3.1. 场景
爆炸性新闻:对象村的湘菜和川菜合并了。
但是湘菜菜谱用的List,川菜菜谱用的数组,新菜单合并中发现每次打印菜单需要用对应的打印方法。
3.2. 不使用Iterator设计模式的代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
/** * Created * Date: 2021/05/25 15:05 <br/> * Description: * 在没有使用迭代器模式时,我们需要针对于各厂商返回的不同数据结构,去适应对应的遍历方式,List的size,Array的length等。 * @author www.loserzhao.com * @see */ public class WithoutIteratorPatternDemo { public static void main(String[] args) { // 集合的遍历 XiangFootMenuItem xiangFootMenuItem = new XiangFootMenuItem(); List<MenuItem> xiangFootMenuItems = xiangFootMenuItem.getMenuItems(); for(int i=0; i<xiangFootMenuItems.size(); i++){ System.out.println(xiangFootMenuItems.get(i)); } // 数组的遍历 ChuanFootMenuItem chuanFootMenuItem = new ChuanFootMenuItem(); MenuItem[] chuanFootMenuItems = chuanFootMenuItem.getMenuItems(); for(int i=0; i<chuanFootMenuItems.length; i++){ System.out.println(chuanFootMenuItems[i]); } } /** * Author: www.loserzhao.com <br/> * Date: 14:17 2021-05-26 <br/> * Description: 湘菜菜单 */ public static class XiangFootMenuItem{ List<MenuItem> menuItems = new ArrayList<MenuItem>(); public XiangFootMenuItem(){ addMenuItem("辣椒炒肉", 28.00); addMenuItem("剁椒鱼头", 48.00); } public void addMenuItem(String name, Double price){ MenuItem menuItem = new MenuItem(name, price); menuItems.add(menuItem); } public List<MenuItem> getMenuItems(){ return menuItems; } } /** * Author: www.loserzhao.com <br/> * Date: 14:18 2021-05-26 <br/> * Description: 川菜菜单 */ public static class ChuanFootMenuItem{ static final int INIT_LENGTH = 2; MenuItem[] menuItems = new MenuItem[INIT_LENGTH]; int index = 0; public ChuanFootMenuItem(){ addMenuItem("麻婆豆腐", 18.00); addMenuItem("重庆火锅", 58.00); addMenuItem("四川辣子鸡", 38.00); } public void addMenuItem(String name, Double price){ MenuItem menuItem = new MenuItem(name, price); if(index == menuItems.length){ MenuItem[] newMenuItems = new MenuItem[this.menuItems.length + INIT_LENGTH]; System.arraycopy(menuItems, 0, newMenuItems, 0, menuItems.length); menuItems = newMenuItems; } menuItems[index++] = menuItem; } public MenuItem[] getMenuItems(){ return menuItems; } } /** * Author: www.loserzhao.com <br/> * Date: 14:16 2021-05-26 <br/> * Description: 菜单 */ public static class MenuItem { private String name; private Double price; public MenuItem() { } public MenuItem(String name, Double price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "MenuItem{" + "name='" + name + '\'' + ", price=" + price + '}'; } } } |
3.3. Iterator模式的代码实现
3.3.1. 当前案例UML
3.3.2. 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
/** * Created * Date: 2021/05/25 15:39 <br/> * Description: * 用了迭代器设计模式后,我们无需关注数据集合类型,迭代器会提供 hasNext(), next()方法来给我们迭代。 * 官方说法:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。 * @author www.loserzhao.com * @see */ public class IteratorPatternDemo { public static void main(String[] args) { XiangFootMenuItem xiangFootMenuItem = new XiangFootMenuItem(); Iterator<MenuItem> xiangFootMenuItemIterator = xiangFootMenuItem.createIterator(); printMenu(xiangFootMenuItemIterator); ChuanFootMenuItem chuanFootMenuItem = new ChuanFootMenuItem(); Iterator<MenuItem> chuanFootMenuItemIterator = chuanFootMenuItem.createIterator(); printMenu(chuanFootMenuItemIterator); } /** * Author: www.loserzhao.com <br/> * Date: 15:08 2021-05-26 <br/> * Description: 打印菜单 * @param menuItemIterator */ public static void printMenu(Iterator<MenuItem> menuItemIterator){ while(menuItemIterator.hasNext()){ System.out.println(menuItemIterator.next()); } } /** * Author: www.loserzhao.com <br/> * Date: 15:08 2021-05-26 <br/> * Description: 迭代器 * @param <E> */ public interface Iterator<E>{ /** * Author: www.loserzhao.com <br/> * Date: 14:36 2021-05-26 <br/> * Description: 是否还有下一个元素 * @return */ Boolean hasNext(); /** * Author: www.loserzhao.com <br/> * Date: 14:37 2021-05-26 <br/> * Description: 获取下一个元素 * @return */ E next(); } /** * Author: www.loserzhao.com <br/> * Date: 15:08 2021-05-26 <br/> * Description: 湘菜迭代器 */ public static class XiangFootMenuItemIterator implements Iterator<MenuItem>{ List<MenuItem> menuItems; int index = 0; public XiangFootMenuItemIterator(List<MenuItem> menuItems){ this.menuItems = menuItems; } public Boolean hasNext() { return index < menuItems.size(); } public MenuItem next() { return menuItems.get(index++); } } /** * Author: www.loserzhao.com <br/> * Date: 15:08 2021-05-26 <br/> * Description: 川菜迭代器 */ public static class ChuanFootMenuItemIterator implements Iterator<MenuItem>{ MenuItem[] menuItems; int index = 0; public ChuanFootMenuItemIterator(MenuItem[] menuItems){ this.menuItems = menuItems; } public Boolean hasNext() { return index < menuItems.length && menuItems[index] != null; } public MenuItem next() { return menuItems[index++]; } } /** * Author: www.loserzhao.com <br/> * Date: 15:08 2021-05-26 <br/> * Description: 菜单聚合类 */ public interface MenuAggregate { /** * Author: www.loserzhao.com <br/> * Date: 15:07 2021-05-26 <br/> * Description: 获取菜单迭代器 * @return */ Iterator<MenuItem> createIterator(); } /** * Author: www.loserzhao.com <br/> * Date: 14:17 2021-05-26 <br/> * Description: 湘菜菜单 */ public static class XiangFootMenuItem implements MenuAggregate { List<MenuItem> menuItems = new ArrayList<MenuItem>(); public XiangFootMenuItem(){ addMenuItem("辣椒炒肉", 28.00); addMenuItem("剁椒鱼头", 48.00); } public void addMenuItem(String name, Double price){ MenuItem menuItem = new MenuItem(name, price); menuItems.add(menuItem); } public Iterator<MenuItem> createIterator(){ return new XiangFootMenuItemIterator(menuItems); } } /** * Author: www.loserzhao.com <br/> * Date: 14:18 2021-05-26 <br/> * Description: 川菜菜单 */ public static class ChuanFootMenuItem implements MenuAggregate { static final int INIT_LENGTH = 2; MenuItem[] menuItems = new MenuItem[INIT_LENGTH]; int index = 0; public ChuanFootMenuItem(){ addMenuItem("麻婆豆腐", 18.00); addMenuItem("重庆火锅", 58.00); addMenuItem("四川辣子鸡", 38.00); } public void addMenuItem(String name, Double price){ MenuItem menuItem = new MenuItem(name, price); if(index == menuItems.length){ MenuItem[] newMenuItems = new MenuItem[this.menuItems.length + INIT_LENGTH]; System.arraycopy(menuItems, 0, newMenuItems, 0, menuItems.length); menuItems = newMenuItems; } menuItems[index++] = menuItem; } public Iterator<MenuItem> createIterator(){ return new ChuanFootMenuItemIterator(menuItems); } } /** * Author: www.loserzhao.com <br/> * Date: 14:16 2021-05-26 <br/> * Description: 菜系 */ public static class MenuItem { private String name; private Double price; public MenuItem() { } public MenuItem(String name, Double price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "MenuItem{" + "name='" + name + '\'' + ", price=" + price + '}'; } } } |
参考文献
《Head First设计模式》
Java 设计模式之迭代器模式
原创文章,转载请注明: 转载自LoserZhao – 诗和远方[ http://www.loserzhao.com/ ]
本文链接地址: http://www.loserzhao.com/java/designpattern/iterator-designpattern.html
文章的脚注信息由WordPress的wp-posturl插件自动生成
0 条评论。