3 完整解决方案

为了简化AbstractObjectList类的结构,并给不同的具体数据集合类提供不同的遍历方式,Sunny软件公司开发人员使用迭代器模式来重构AbstractObjectList类的设计,重构之后的销售管理系统数据遍历结构如图4所示:

图4 销售管理系统数据遍历结构图

(注:为了简化类图和代码,本结构图中只提供一个具体聚合类和具体迭代器类)

在图4中,AbstractObjectList充当抽象聚合类,ProductList充当具体聚合类,AbstractIterator充当抽象迭代器,ProductIterator充当具体迭代器。完整代码如下所示:

[java] view plaincopy
  1. //在本实例中,为了详细说明自定义迭代器的实现过程,我们没有使用JDK中内置的迭代器,事实上,JDK内置迭代器已经实现了对一个List对象的正向遍历
  2. import java.util.*;
  3. //抽象聚合类
  4. abstract class AbstractObjectList {
  5. protected List<Object> objects = new ArrayList<Object>();
  6. public AbstractObjectList(List objects) {
  7. this.objects = objects;
  8. }
  9. public void addObject(Object obj) {
  10. this.objects.add(obj);
  11. }
  12. public void removeObject(Object obj) {
  13. this.objects.remove(obj);
  14. }
  15. public List getObjects() {
  16. return this.objects;
  17. }
  18. //声明创建迭代器对象的抽象工厂方法
  19. public abstract AbstractIterator createIterator();
  20. }
  21. //商品数据类:具体聚合类
  22. class ProductList extends AbstractObjectList {
  23. public ProductList(List products) {
  24. super(products);
  25. }
  26. //实现创建迭代器对象的具体工厂方法
  27. public AbstractIterator createIterator() {
  28. return new ProductIterator(this);
  29. }
  30. }
  31. //抽象迭代器
  32. interface AbstractIterator {
  33. public void next(); //移至下一个元素
  34. public boolean isLast(); //判断是否为最后一个元素
  35. public void previous(); //移至上一个元素
  36. public boolean isFirst(); //判断是否为第一个元素
  37. public Object getNextItem(); //获取下一个元素
  38. public Object getPreviousItem(); //获取上一个元素
  39. }
  40. //商品迭代器:具体迭代器
  41. class ProductIterator implements AbstractIterator {
  42. private ProductList productList;
  43. private List products;   // 保存聚合类中的集合对象
  44. private int cursor1; //定义一个游标,用于记录正向遍历的位置
  45. private int cursor2; //定义一个游标,用于记录逆向遍历的位置
  46. public ProductIterator(ProductList list) {
  47. this.productList = list;
  48. this.products = list.getObjects(); //获取集合对象
  49. cursor1 = 0; //设置正向遍历游标的初始值
  50. cursor2 = products.size() -1; //设置逆向遍历游标的初始值
  51. }
  52. public void next() {
  53. if(cursor1 < products.size()) {
  54. cursor1++;
  55. }
  56. }
  57. public boolean isLast() {
  58. return (cursor1 == products.size());
  59. }
  60. public void previous() {
  61. if (cursor2 > -1) {
  62. cursor2--;
  63. }
  64. }
  65. public boolean isFirst() {
  66. return (cursor2 == -1);
  67. }
  68. public Object getNextItem() {
  69. return products.get(cursor1);
  70. }
  71. public Object getPreviousItem() {
  72. return products.get(cursor2);
  73. }
  74. }

编写如下客户端测试代码:

[java] view plaincopy
  1. class Client {
  2. public static void main(String args[]) {
  3. List products = new ArrayList();
  4. products.add("倚天剑");
  5. products.add("屠龙刀");
  6. products.add("断肠草");
  7. products.add("葵花宝典");
  8. products.add("四十二章经");
  9. AbstractObjectList list;
  10. list = new ProductList(products); //创建聚合对象
  11. // ...此处操作聚合类的数据
  12. AbstractIterator iterator = list.createIterator();   //创建迭代器对象
  13. System.out.println("正向遍历:");
  14. while(!iterator.isLast()) {
  15. System.out.print(iterator.getNextItem() + ",");
  16. iterator.next();
  17. }
  18. System.out.println();
  19. System.out.println("-----------------------------");
  20. System.out.println("逆向遍历:");
  21. while(!iterator.isFirst()) {
  22. System.out.print(iterator.getPreviousItem() + ",");
  23. iterator.previous();
  24. }
  25. }
  26. }

编译并运行程序,输出结果如下:

正向遍历:

倚天剑,屠龙刀,断肠草,葵花宝典,四十二章经,

-----------------------------

逆向遍历:

四十二章经,葵花宝典,断肠草,屠龙刀,倚天剑,

如果需要增加一个新的具体聚合类,如客户数据集合类,并且需要为客户数据集合类提供不同于商品数据集合类的正向遍历和逆向遍历操作,只需增加一个新的聚合子类和一个新的具体迭代器类即可,原有类库代码无须修改,符合“开闭原则”;如果需要为ProductList类更换一个迭代器,只需要增加一个新的具体迭代器类作为抽象迭代器类的子类,重新实现遍历方法,原有迭代器代码无须修改,也符合“开闭原则”;但是如果要在迭代器中增加新的方法,则需要修改抽象迭代器源代码,这将违背“开闭原则”。

【作者:刘伟   http://blog.csdn.net/lovelion

迭代器模式(三):销售管理系统中数据的遍历的迭代器模式解决方案相关推荐

  1. vue数组中数据变化但是视图没有更新解决方案

    vue数组中数据变化但是视图没有更新解决方案 参考文章: (1)vue数组中数据变化但是视图没有更新解决方案 (2)https://www.cnblogs.com/sufubo/p/6906261.h ...

  2. redis中数据倾斜问题的产生和解决方案

    在服务端系统服务开发中,缓存是一种常用的技术,它可以提高系统对请求的处理效率,而redis又是缓存技术栈中的一个佼佼者,广泛的应用于各种服务系统中.在大型互联网服务中,每天需要处理的请求和存储的缓存数 ...

  3. c语言图书馆管理系统中数据存放位置,c语言数据结构图书馆系统

    //#define var 333; //移动光标位置 void gotoxy(int x,int y) { COORD xy; HANDLE hstdout; hstdout=GetStdHandl ...

  4. 数据结构(三)打印二叉树中结点层次遍历序列的实现

    1.实验目的: 掌握二叉树的结构特性以及二叉链表的存储结构的特点及适用范围.同时,掌握用指针类型描述.访问和处理二叉树的运算. 2.试验问题: 建立一棵二叉树,按层次遍历该二叉树,并显示出这棵二叉树. ...

  5. MySQL中数据插入与主键冲突解决方案

    在插入数据的时候,有时候会遇到主键(唯一键)冲突的情况.下面讲述两种解决办法. [1] 更新原数据 insert into 表名[(字段列表:包含主键)] values(值列表) on duplica ...

  6. 家具销售管理系统/家具在线商城

    目  录 摘  要 前  言 2 第1章 概述 2 1.1 研究背景 3 1.2 研究目的 3 1.3 研究内容 4 第二章 开发技术介绍 5 2.1相关技术 5 2.2 Java技术 6 2.3 M ...

  7. asp.net销售管理系统的设计和实现

    目录 1.绪论 1 (一)选题背景 1 (二)系统描述 1 (三)系统开发目的和意义 1 2.汇银电子商务公司系统开发分析 2 (一)汇银电子商务公司系统开发工具分析 2 ASP.net概述 2 SQ ...

  8. 鲜花线上销售管理系统的设计与实现

    作者主页:编程千纸鹤 作者简介:Java.前端.Pythone开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发.毕业设计开发.面试技术整理.最新技术分享 一,项目简介 鲜花线上销售管理 ...

  9. java毕业设计——基于java+JSP+Tomcat的农产品销售管理系统设计与实现(毕业论文+程序源码)——农产品销售管理系统

    基于java+JSP+Tomcat的农产品销售管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+JSP+Tomcat的农产品销售管理系统设计与实现,文章末尾附有本毕业设计的 ...

最新文章

  1. 深入理解abstract class和interface
  2. 深入理解JVM(4)——如何优化Java GC「译」
  3. 10 种保护 Spring Boot 应用的绝佳方法
  4. 权重初始化时除以前一层的神经元个数开方的意义
  5. TensorFlow数据读取机制:文件队列 tf.train.slice_input_producer和 tf.data.Dataset机制
  6. python nonetype报错_python 查询数据库数据 NoneType报错
  7. 大中型网站使用图片域名的必要性原因
  8. 获取地球某点最新的磁偏角
  9. spring切点表达式提取jdk版本与aspectjweaver版本不匹配
  10. 常见名称解析_著名软件著名计算机语言
  11. Tmux常用命令小结(超全够用)
  12. 我的2021年终回顾:一如少年,眼眸有星辰,心中有山海
  13. 机器学习笔记--PR曲线和ROC曲线
  14. android 通讯录搜索算法,一个简单的通讯录联系人拼音匹配算法
  15. 中国新零售行业展望及十四五发展规划建议报告2022-2028年
  16. 苹果皮被“山寨”:iPhone也能支持4G网络
  17. ultraiso软碟通注册码
  18. seata-server
  19. 深度学习实战1(基本概念、全连接神经网络、CNN)
  20. 爬取数据并写入MySQL数据库

热门文章

  1. 一周新闻纵览:如何加强个人信息保护? 网信办正在做这四方面工作;微软麻将Al来了;银行花式营销ETC“套路”引争议
  2. 【银河麒麟V10】【服务器】麒麟容器常见问题
  3. 如何同时给多段视频制作翻转画面的效果
  4. 拳打“友商”,脚踢高通,荣耀9X收割4G时代最后红利
  5. 硕盟 SM-T66type-c扩展坞转HDMI
  6. 移花接木—做一个简单的软件渲染器
  7. FT232R USB UART 驱动安装问题
  8. 不了解基金拆分的基民们,一定要看,一定要,有钱也难买的深度分析: zz
  9. c51单片机秒表程序c语言,利用51单片机制作秒表的详细过程
  10. DEVC++出现编译运行后停止工作的问题