文章目录
- 想走?可以!先买票——迭代器模式
- 乘车买票,不管你是谁!
- 迭代器模式
- 迭代器实现
- Java的迭代器实现
- 迭代高手
想走?可以!先买票——迭代器模式
乘车买票,不管你是谁!
时间:5月26日10点 地点:一辆公交车上 人物:小菜、大鸟、售票员、公交乘客、小偷
这天是周末,小菜和大鸟一早出门游玩,上了公交车,车内很拥挤。
"上车的乘客请买票。"售票员一边在人缝中穿插着,一边说道。
……
"先生,您这包行李太大了,需要补票的。"售票员对一位拿着大包行李的乘客说道。
"哦,这也需要买票呀,它又不是人。"带大包行李的乘客说。
"您可以看看规定,当您携带的行李占据了一个客用面积时,请再购买同程车票一张,谢谢合作。"售票员指了指车上的一个纸牌子。
这位乘客很不情愿地再买了一张票。
“还有三位乘客没有买票,请买票!”
……
"这售票员够厉害,记得这么清楚,上来几个人都记得。"小菜感叹道。
"这也是业务能力的体现呀。"大鸟解释说。
……
"先生请买票!"售票员对着一位老外说道。
"Sorry,What do you say?"老外看来不会中文。
"请买车票怎么说?"售票员低声地自言自语道,“Please buy ……票怎么说……”
"ticket,"小菜手掌放嘴边,小声地提醒了一句。
" 谢 谢 , " 售 票 员 对 小 菜 笑 了 笑 , 接 着 用 中 国 式 英 文 对 着 老 外 说道,“Please buy a ticket.”
"Oh!yes."老外急忙掏钱包拿了一张十元人民币。
"买票了,买票了,还有两位,不要给不买票的人任何机会……"售票员
找了老外钱后吆喝着,又对着一穿着同样公交制服的女的说道,“小姐,请买票!”
"我也是公交公司的,"这女的拿出一个公交证件,在售票员面前晃了晃。
"不好意思,公司早就出规定了,工作证不得作为乘车凭证。"售票员说道。
"我乘车从来就没买过票,凭什么在这就要买票。"这个乘客开始耍赖。
此时旁边的乘客都来劲了,七嘴八舌说起来。
“公交公司的员工就不是乘客呀,国家总理来也要买票的。”
“这人怎么这样,想占大伙的便宜呀。”
“你还当过去呀,现在不吃大锅饭了。欠债还钱,乘车买票,天经地义……”
"行了行了,不就是一张票吗,搞什么搞。"这不想买票的小姐终于扛不住了,扫码买了票。
"还有哪一位没有买票,请买票。"售票员继续在拥挤的车厢里跋涉着。
"小偷!你这小偷,把手机还我。"突然站在小菜不远处的一小姑娘对着一猥琐的男人叫了起来。
“你不要乱讲,我哪有偷你手机。”
“我看见你刚才把手伸进了我的包里。就是你偷的。”
“我没有偷,你看错了。”
"我明明看见你偷的。"小姑娘急得哭了出来。
小菜看不过去了,“你的手机号多少,我帮你打打看。”
"138xxxx8888"小姑娘像是看到了希望。
"哇,这么强的号,手机一定不会丢。"小菜羡慕着,用自己的手机拨了这个号码。
那人眼看着不对,想往门口跑,小菜和大鸟冲了上去,一把按住他。
"你看,我的手机响了,就在他身上。"小姑娘叫了起来,“就是他,他就是小偷。”
此时两个小伙已经把猥琐男死死按在了地板上。
"快打110报警!"大鸟喊道。
此时公交车也停了下来,所有的乘客都议论着"小偷真可恶"的话题。
不一会儿,民警来了,问清楚了来由,正准备将小偷带走时,售票员对着小偷发话了:“慢着,你是那个没有买票的人吧?”
"啊?嗯!是的。"小偷一脸沮丧回答道。
"想走?先买票再说!"售票员干脆地说。
小菜和大鸟对望一眼,异口同声道:“强!”
……
迭代器模式
"小菜,今天你真见到强人了吧?"大鸟在下车后,对小菜说道。"这个售票员,实在够强,"小菜学着模仿道,“想走?!可以。先买票再说!”
“这售票员其实在做一件重要的事,就是把车厢里的所有人都遍历了一遍,不放过一个不买票的乘客。这也是一个设计模式的体现。”
“大鸟,你也够强,什么都可以往设计模式上套,这也是模式?”
“当然是模式。这个模式就叫作迭代器模式。”
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。[DP]
“你想呀,售票员才不管你上来的是人还是物(行李),不管是中国人还是外国人,不管是不是内部员工,甚至哪怕是马上要抓走的小偷,只要是来乘车的乘客,就必须要买票。同样道理,当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。另外,售票员从车头到车尾来售票,也可以从车尾向车头来售票,也就是说,你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。由于不管乘客是什么,售票员的做法始终是相同的,都是从第一个开始,下一个是谁,是否结束,当前售到哪个人了,这些方法每天他都在做,也就是说,为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。”
“听你这么一说,好像这个模式也不简单哦。”
“哈,本来这个模式还是有点意思的,不过现今来看迭代器模式实用价值远不如学习价值大了,Martin Flower甚至在自己的网站上提出撤销此模式。因为现在高级编程语言如C#、Java等本身已经把这个模式做在语言中了。”
“哦,是什么?”
“哈,foreach你熟悉吗?”
“啊,原来是它,没错没错,它就是不需要知道集合对象是什么,就可以遍历所有的对象的循环工具,非常好用。”
“另外还有像Iterator接口也是为迭代器模式而准备的。不管如何,学习一下GoF的迭代器模式的基本结构,还是很有学习价值的。研究历史是为了更好地迎接未来。”
迭代器实现
Aggregate聚集抽象类:
ConcreteAggregate具体聚集类:继承Aggregate。
ConcreteIterator具体迭代器类:继承Iterator。
结果显示:
“看到没有,这就是我们的优秀售票员售票——迭代器的整个运作模式。”
“大鸟,你说为什么要用具体的迭代器ConcreteIterator来实现抽象的Iterator呢?我感觉这里不需要抽象呀,直接访问ConcreteIterator不是更好吗?”
“哈,那是因为刚才有一个迭代器的好处你没注意,当你需要对聚集有多种方式遍历时,可以考虑用迭代器模式,事实上,售票员一定要从车头到车尾这样售票吗?”
“你意思是,他还可以从后向前遍历?”
“当然可以,你不妨再写一个实现从后往前的具体迭代器类看看。”
“好的。”
“写得不错,这时你客户端只需要更改一个地方就可以实现反向遍历了。”
"是呀,其实售票员完全可以用更多的方式来遍历乘客,比如从最高的到最矮的、从最小到最老、从最靓丽酷毙到最猥琐龌龊。"小菜已经开始头脑风暴。
"神经病,你当是你呀。"大鸟笑骂。
Java的迭代器实现
“刚才我们也说过,实际使用当中是不需要这么麻烦的,因为Java语言中已经为你准备好了相关接口,你只需去实现就好。”
Java.util.Iterator支持对集合的简单迭代接口。
“你会发现,这两个接口要比我们刚才写的抽象类Iterator简洁,但可实现的功能却一点不少,这其实也是对GoF的设计改良的结果。”
“其实具体类实现这两个接口的代码也差别不大,是吗?”
“是的,区别不大,另外这两个是可以实现泛型的接口,去查Java的API帮助就可以了。”
“有了这个基础,你再来看你最熟悉的foreach就很简单了。”
“这里用到了foreach而在编译器里做了些什么呢?其实它做的是下面的工作。”
“原来foreach就是实现Iterator来实际循环遍历呀。”
“如果我们想实现刚才的反向遍历。那就用另一个接口实现。”
“是的,尽管我们不需要显式地引用迭代器,但系统本身还是通过迭代器来实现遍历的。总的来说,迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。迭代器模式在访问数组、集合、列表等数据时,尤其是数据库数据操作时,是非常广泛的应用,但由于它太普遍了,所以各种高级语言都对它进行了封装,所以反而给人感觉此模式本身不太常用了。”
迭代高手
“哈哈,看来那个售票员是最了不起的迭代高手,每次有乘客上车他都数数,统计人数,然后再对整车的乘客进行迭代遍历,不放过任何漏网之鱼,啊,应该是逃票之人。”
“隔行如隔山,任何行业都有技巧和经验,需要多思考、多琢磨,才能做到最好的。”
“嗯,编程又何尝不是这样,我相信代码没有最好,只有更好,我要继续努力。”
如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~