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. 【ArcGIS 10.2新特性】Geodatabase 10.2 常见问题
  2. 你知道Linux和Unix的区别吗
  3. 如何在Safari中查看网页的完整URL
  4. java多表查询返回数据_spring data jpa如何在多张数据库表中查询返回某些字段值?...
  5. iQOO Z5内置5000mAh大电池:超长续航安全感爆棚
  6. 算法(第四版)C# 习题题解——1.2
  7. [转载]Qt之获取本机网络信息_vortex_新浪博客
  8. Python 语言使用中遇到的问题汇总
  9. 新手购买单反终极攻略--谈谈现场验机的要领与要点
  10. MATLAB卷积运算(conv)以及通用的卷积函数my_conv的实现
  11. 利用MATLAB进行shp文件转换并绘制断层线
  12. Threejs 加载3D模型
  13. excel单元格数字拆分比较
  14. vbs 打开指定浏览器网页
  15. 12个面向前端开发者真正有用的 VSCode 插件工具
  16. MBA-day13数学-年龄问题-应用题
  17. CodeUp-1036 Problem B 镂空三角形
  18. opporeno6pro+和reno5pro+参数配置详细
  19. Microsoft Windows CredSSP 远程执行代码漏洞CVE-2018-0886
  20. Android 联想K5 Play 8.0 Notification突破拦截(vdex反编译 )

热门文章

  1. tfidf和word2vec构建文本词向量并做文本聚类
  2. 笔记本电脑CPU正常温度是多少?怎样控制与防范?
  3. android js shell,利用adb shell和node.js实现抖音自动抢红包功能(推荐)
  4. IIS服务器小白基础
  5. ftp 客户端,9款超级好用而且免费的ftp 客户端,你值得拥有
  6. 建议别买三星Gear:半电脑产品 设计糟糕
  7. 使用VB.NET控制台应用程序实现一个简单的计算器
  8. Kubernetes集群一键化部署
  9. CAD2010软件中点样式设置命令
  10. qmc5883p芯片坐标系方向定义