设计模式系列漫谈之五 - 迭代器模式
故事
小美是小雪最好的朋友。有一天, 小美问小雪:“小雪,怎么你的手机短信这么多啊,是不是谈恋爱了?”,小雪笑了一下,说:“还没呢”,小雪停顿了一下,“可是喜欢我的男孩倒是很多,这些男孩都不错,眼都快花了”。小美想了想:“跟我说说这些男孩子,我帮你选一个最优秀的”。
果然,小美开始给小雪策划了一个钻石王老五大调查(遍历):
1) 年龄小于30大于35者出局;
2) 身高低于180cm者出局;
3) 无房者出局;
4) 无车者出局;
5) 年薪低于100万者出局。
迭代器模式(ITerator)的解决方案
迭代器模式的意图:通过顺序遍历或逆序遍历等方式访问集合对象(List)中的各元素子对象(object)。一般来说,一个集合对象拥有两个职责:一是存储一组元素子对象;二是遍历集合中的各元素子对象。从依赖性来讲,前者是集合对象的根本属性;后者是可分离的变化点。
子对象接口如下:
namespace XiaoXue
{
public interface IBoy
{
string Name{get;}
int GetAge();
int GetHeight();
bool HasHouse();
bool HasCar();
bool HasMillion();
}
}
{
public interface IBoy
{
string Name{get;}
int GetAge();
int GetHeight();
bool HasHouse();
bool HasCar();
bool HasMillion();
}
}
子对象具体类如下:
namespace XiaoXue
{
public class BoyA : IBoy
{
private string _Name="张三";
public string Name
{
get{ return _Name;}
}
public int GetAge()
{
return 25;
}
public int GetHeight()
{
return 187;
}
public bool HasHouse()
{
return true;
}
public bool HasCar()
{
return false;
}
public bool HasMillion()
{
return false;
}
}
public class BoyB : IBoy
{
private string _Name="李四";
public string Name
{
get{ return _Name;}
}
public int GetAge()
{
return 32;
}
public int GetHeight()
{
return 170;
}
public bool HasHouse()
{
return true;
}
public bool HasCar()
{
return true;
}
public bool HasMillion()
{
return true;
}
}
}
{
public class BoyA : IBoy
{
private string _Name="张三";
public string Name
{
get{ return _Name;}
}
public int GetAge()
{
return 25;
}
public int GetHeight()
{
return 187;
}
public bool HasHouse()
{
return true;
}
public bool HasCar()
{
return false;
}
public bool HasMillion()
{
return false;
}
}
public class BoyB : IBoy
{
private string _Name="李四";
public string Name
{
get{ return _Name;}
}
public int GetAge()
{
return 32;
}
public int GetHeight()
{
return 170;
}
public bool HasHouse()
{
return true;
}
public bool HasCar()
{
return true;
}
public bool HasMillion()
{
return true;
}
}
}
迭代器接口如下:
namespace XiaoXue
{
public interface IListIterator
{
void First();
void Last();
bool MovePrevous();
bool MoveNext();
object Current{get;}
}
}
{
public interface IListIterator
{
void First();
void Last();
bool MovePrevous();
bool MoveNext();
object Current{get;}
}
}
迭代器如下:
namespace XiaoXue
{
public class BoyList:IListIterator
{
private List<IBoy> boys = null;//子对象列表
private int index=-1;
public BoyList()
{
boys = new List<IBoy>();
}
//添加子对象
public void AddBoy(IBoy boy)
{
boys.Add(boy);
}
public void RemoveBoy(IBoy boy)
{
boys.Remove(boy);
index--;
}
public void First()
{
index=0;
}
public void Last()
{
index=boys.Count;
}
public bool MovePrevious()
{
index--;
return index>-1;
}
public bool MoveNext()
{
index++;
return index<boys.Count;
}
public object Current
{
get {return this.boys[index];}
}
}
}
{
public class BoyList:IListIterator
{
private List<IBoy> boys = null;//子对象列表
private int index=-1;
public BoyList()
{
boys = new List<IBoy>();
}
//添加子对象
public void AddBoy(IBoy boy)
{
boys.Add(boy);
}
public void RemoveBoy(IBoy boy)
{
boys.Remove(boy);
index--;
}
public void First()
{
index=0;
}
public void Last()
{
index=boys.Count;
}
public bool MovePrevious()
{
index--;
return index>-1;
}
public bool MoveNext()
{
index++;
return index<boys.Count;
}
public object Current
{
get {return this.boys[index];}
}
}
}
调用代码如下:
IListIterator iterator=new BoyList();
iterator.AddBoy(new BoyA());
iterator.AddBoy(new BoyB());
while (iterator.MoveNext())
{
IBoy boy=(IBoy)iterator.Current
if (boy.GetAge()<30 || boy.GetAge()>35)
{
iterator.RemoveBoy(boy);
}
else if (boy.GetHeight()<180)
{
iterator.RemoveBoy(boy);
}
else if (!boy.HasHouse())
{
iterator.RemoveBoy(boy);
}
else if (!boy.HasCar())
{
iterator.RemoveBoy(boy);
}
else if (!boy.HasMillion())
{
iterator.RemoveBoy(boy);
}
else
{
Console.WriteLine(boy.Name);
}
}
iterator.AddBoy(new BoyA());
iterator.AddBoy(new BoyB());
while (iterator.MoveNext())
{
IBoy boy=(IBoy)iterator.Current
if (boy.GetAge()<30 || boy.GetAge()>35)
{
iterator.RemoveBoy(boy);
}
else if (boy.GetHeight()<180)
{
iterator.RemoveBoy(boy);
}
else if (!boy.HasHouse())
{
iterator.RemoveBoy(boy);
}
else if (!boy.HasCar())
{
iterator.RemoveBoy(boy);
}
else if (!boy.HasMillion())
{
iterator.RemoveBoy(boy);
}
else
{
Console.WriteLine(boy.Name);
}
}
哈哈, 好象没有一个符合条件的,俗话说:“什么样的马配什么样的鞍”。这样的王老五只有到月球上去找吧!