“田忌赛马”的故事大家从小就听说过了吧,如果我没记错的话,小学课文中就有这样一篇(当然是我们那个年代的了)。
田忌在赛马过程中采取的对策正好跟设计模式中的迭代器模式不谋而合。田忌和对手每次都要从3匹能力参差不齐的马中选出1匹来和对手比试,最后谁赢的次数最多谁就获胜。
大家都知道,田忌之所以获胜,就是因为他用自己的劣等马去拼对方的优等马,然后用自己的优等马比对方的中等马,最后再用自己的中等马去赢对方的劣等马,2比1,因此田忌获胜,这个故事也就流芳百世。这说明两点问题:1,古人大多很实心眼儿,所以一个小小的把戏就可能把对方耍得团团转;2,人类的智慧是前人智慧的叠加再乘以一个遗忘系数所得的结果,我们今天之所以觉得田忌的对手简直笨得可爱,是因为我们的智慧是建立在古人的智慧基础之上的。
不扯远了,还是说说“田忌赛马”跟“迭代器模式”有什么关系吧。简而言之,迭代器的中心思想就是:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。可想而知,选马就是一个遍历的过程,而遍历的的方式和其元素在内部的表示(优、良、差)又是不暴露出来的,如果对方知道田忌怎么选马、每次都选的是什么马,那么田忌也就没有任何胜算了(至少要想战胜对方就变得相当困难了)。
1: using System;
2: using System.Collections;
3:
4: namespace Autumoon.DesignPatterns.Iterator
5: {
6: public class Node
7: {
8: public string Name { get; set; }
9:
10: public Node(string name)
11: {
12: this.Name = name;
13: }
14: }
15:
16: public class NodeCollection
17: {
18: private ArrayList list = null;
19: public int NodeMax { get; private set; }
20:
21: public void AddNode(Node node)
22: {
23: if (list == null)
24: {
25: list = new ArrayList();
26: }
27:
28: list.Add(node);
29:
30: this.NodeMax++;
31: }
32:
33: public Node GetNode(int index)
34: {
35: return ((Node)list[index]);
36: }
37: }
38:
39: public abstract class Iterator
40: {
41: abstract public Node Next();
42: }
43:
44: public class ReverseIterator : Iterator
45: {
46: private NodeCollection nodeCollection;
47: private int currentIndex = -1;
48:
49: public ReverseIterator(NodeCollection nodes)
50: {
51: nodeCollection = nodes;
52: currentIndex = nodes.NodeMax - 1;
53: }
54:
55: override public Node Next()
56: {
57: return (currentIndex >= 0 ? (nodeCollection.GetNode(currentIndex--)) : null);
58: }
59: }
60: }
好了,赛马开始!
1: static void Main(string[] args)
2: {
3: #region Iterator
4: NodeCollection nodes = new NodeCollection();
5: nodes.AddNode(new Node("A"));
6: nodes.AddNode(new Node("B"));
7: nodes.AddNode(new Node("C"));
8:
9: ReverseIterator iterator = new ReverseIterator(nodes);
10: Node node = null;
11:
12: while ((node = iterator.Next()) != null)
13: {
14: Console.WriteLine(node.Name);
15: }
16: #endregion
17:
18: Console.ReadLine();
19: }