【手写源码-设计模式17】-迭代器模式-基于客户与商品数据遍历
1:主题拆解
①基本介绍
②客户与商品数据遍历
③迭代器模式的优缺点
④适用场景
⑤应有实例
2:基本介绍
提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。
迭代器模式的结构如下
①抽象容器
一般是一个接口,提供一个iterator()方法。
②具体容器
就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
③抽象迭代器
定义遍历元素所需要的方法,一般来说会有这么三个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移出当前对象的方法remove(),
④迭代器实现
实现迭代器接口中定义的方法,完成集合的迭代。
3:客户与商品数据遍历
①定义数据实体
public class DataEntity
{public int Id { get; set; }public string Name { get; set; }public int Price { get; set; }
}
②客户与商品实例类
public class CustomerMenu
{private DataEntity[] _EntityList = new DataEntity[3];public CustomerMenu(){this._EntityList[0] = new DataEntity(){Id = 1,Name = "华为",Price = 15};this._EntityList[1] = new DataEntity(){Id = 2,Name = "小米",Price = 10};this._EntityList[2] = new DataEntity(){Id = 3,Name = "Apple",Price = 8};} public DataEntity[] GetEntity(){return this._EntityList;}public IIterator<DataEntity> GetIterator(){return new KFCMenuIterator(this);}
}
public class ProductMenu
{private List<DataEntity> _EntityList = new List<DataEntity>();public ProductMenu(){this._EntityList.Add(new DataEntity(){Id = 1,Name = "华为P40Pro",Price = 15});this._EntityList.Add( new DataEntity(){Id = 2,Name = "小米X Max",Price = 10});this._EntityList.Add(new DataEntity(){Id = 3,Name = "IPhone 13 Plus",Price = 9});}public List<DataEntity> GetEntity(){return this._EntityList;}public IIterator<DataEntity> GetIterator(){return new ProductMenuIterator(this);}
}
③迭代器基类
public interface IIterator<T>
{T Current { get; }bool MoveNext();void Reset();
}
④新的集合实现IIterator接口
public class CustomerMenuIterator : IIterator<DataEntity>
{private DataEntity[] _FoodList = null;public CustomerMenuIterator(CustomerMenu menu){this._FoodList = menu.GetEntity();}private int _Index = -1;public DataEntity Current{get{return this._FoodList[_Index];}}public bool MoveNext(){return this._FoodList.Length > ++this._Index;}public void Reset(){this._Index = -1;}
}
public class ProductMenuIterator : IIterator<DataEntity>
{private List<DataEntity> _FoodList = null;public ProductMenuIterator(ProductMenu menu){this._FoodList = menu.GetEntity();}private int _Index = -1;public DataEntity Current{get{return this._FoodList[_Index];}}public bool MoveNext(){return this._FoodList.Count > ++this._Index;}public void Reset(){this._Index = -1;}
}
⑤上端调用
CustomerMenu customerMenu = new CustomerMenu();
DataEntity[] foods = customerMenu.GetEntity();
IIterator<DataEntity> iteratorCustomer = customerMenu.GetIterator();
while (iteratorCustomer.MoveNext())
{DataEntity itemCustomer = iteratorCustomer.Current;Console.WriteLine("{0} {1} {2}", itemCustomer.Id, itemCustomer.Name, itemCustomer.Price);
}ProductMenu productMenu = new ProductMenu();
IIterator<DataEntity> iteratorProduct = productMenu.GetIterator();
while (iteratorProduct.MoveNext())
{DataEntity itemProduct = iteratorProduct.Current;Console.WriteLine("{0} {1} {2}", itemProduct.Id, itemProduct.Name, itemProduct.Price);
}
⑥执行结果
4:迭代器模式的优缺点
1:优点
①多种遍历方式
支持以不同方式遍历聚合对象,在同一聚合对象上可以定义多种遍历方法,只需要用一个不同的聚合器替换原来的迭代器即可改变遍历算法。
②简化聚合类
原有的聚合对象不需要再自行提供数据遍历方法。
②满足OCP
由于引入了抽象层,增加新的聚合类以及迭代器类都很方便,无须修改源码。
2:缺点
①复杂度增加
迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,增加了复杂性。
②抽象迭代器较难设计
考虑到以后的扩展,抽象迭代器的设计难度可能非常大,比如JDK的内置迭代器Iterator就无法实现逆向遍历,设计一个考虑全面的抽象迭代器并不是一件容易的事。
5:适用场景
①访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据存储分离,使得访问聚合对象时无须了解内部实现细节。
②需要为一个聚合对象提供多种遍历方式。
③为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。
6:应用实例
List
Arrary
IEnumerable
【手写源码-设计模式17】-迭代器模式-基于客户与商品数据遍历相关推荐
- 【手写源码-设计模式6】-适配器模式-基于IPhoneX手机充电场景
1:主题拆解 ①基本介绍 ②IPhone手机充电场景模拟 ③类适配器与对象适配器的区别 ④适配器模式的优缺点 ⑤适用场景 ⑥C#.NET中的使用场景 2:基本介绍 Adapter适配器模式,将一个类的 ...
- 【手写源码-设计模式15】-责任链模式-基于人事请假单工作流场景
1:主题拆解 ①基本介绍 ②人事请假单工作流模拟 ③责任链模式的优缺点 ④适用场景 ⑤应用实例 ⑥ASP.NET 管道模型 2:基本介绍 责任链模式很像异常的捕获和处理,当一个问题发生的时候,当前对象 ...
- 前端为什么有的接口明明是成功回调却执行了.catch失败回调_前端进阶高薪必看-手写源码篇(高频技术点)...
前言 此系列作为笔者之前发过的前端高频面试整理的补充 会比较偏向中高前端面试问题 当然大家都是从新手一路走过来的 感兴趣的朋友们都可以看哈 初衷 我相信不少同学面试的时候最怕的一个环节就是手写代码 大 ...
- all方法 手写promise_前端进阶高薪必看手写源码篇
前言 此系列作为笔者之前发过的前端高频面试整理的补充 会比较偏向中高前端面试问题 当然大家都是从新手一路走过来的 感兴趣的朋友们都可以看哈 初衷 我相信不少同学面试的时候最怕的一个环节就是手写代码 大 ...
- fortran中call的用法_手写源码系列(一)——call、apply、bind
什么是手写源码 平时面试时经常会遇到让手写一个已有方法的实现,其实面试官是想考察你对于JS底层逻辑是否熟悉,经常面试会出的会在下面: call.apply.bind promise requireJS ...
- TransmittableThreadLocal的简单使用 + 手写源码
文章目录 使用方法 原理 手写源码 之前有一篇文章谈到链路追踪场景下,需要在异步线程之间,实现跨线程的ThreadLocal传递, 简单场景可以用InheritableThreadLocal,但ITL ...
- 面试前端岗,你被要求手写源码了吗?
如今前端开发的任职要求越来越高了,不仅要掌握 javascript,熟悉vue.react等各种框架,甚至连后端和 python 都得懂. 前几年只要熟练HTML.CSS.JavaScript ,靠扒 ...
- 卡牌类手游源码 刀塔传奇 免费分享 基于cocos2d-x3.0引擎开发
卡牌类手游源码 刀塔传奇 免费分享 基于cocos2d-x3.0引擎开发 https://bbs.wxrym.com/thread-90118-1-1.html (出处: 外星人源码论坛) 今天给大家 ...
- 【设计模式-手写源码-附1】-简单工厂模式-基于魔兽争霸冰封王座
1:主题拆解 ①依赖倒置原则-SimpleFactory ②简单工厂+ 配置文件=可配置 ③简单工厂+ 配置文件+反射=可配置可扩展 ④简单工厂升级IOC控制反转 2:基本介绍 ①学习设计模式的套路: ...
- 【设计模式-手写源码-2】-工厂方法模式-基于魔兽争霸冰封王座
1:主题拆解 ① 对比简单工厂,建立工厂方法(FactoryMethod) ②工厂方法的优缺点和应用 ③对修改关闭对扩展开放 ④面向切面编程 2:基本介绍 定义一个用于创建对象的接口,让子类决定实例化 ...
最新文章
- 【每日一算法】爬楼梯
- iOS开发socket程序被SIGPIPE信号Terminate的问题
- thinkPHP学习笔记
- react源码解读 {createClass}
- 程序员:站在自学鄙视链顶端的王者(太真实!)
- linux怎么实时查看目录下是否有文件生成
- 用glew,glfw,FreeImag实现opengl画图-第五课 摄像机
- javascript 内存和连等赋值
- Java 并发编程实战 -- 常见概念
- C#实战之CAD二次开发005:打印pdf
- 运用Excel实现描述性统计分析
- SecureCRT 破解版v7.1.1.264中文汉化绿色版
- ACM/IOI 国家队集训队论文集锦
- 空城计课件软件测试,空城计课件参考
- WAF绕过技术系列文章(一)
- 2020年12月统考练习题
- 莫道C站小,这边风景独好~
- 我在工作中是如何使用【Linux】的
- 五款最出色的数据恢复工具
- Spring Boot 起步依赖