前言
今天复习了迭代器模式,虽然已被C++语言中访问容器的迭代器算法取代,实用价值不高,但是仍然值得学习,对底层STL迭代器算法的理解很有帮助。
1. 迭代器模式的理解
迭代器模式,和STL的迭代器算法原理相同,都是对多元素对象的遍历访问,并且不用知道对象的具体实现细节。
迭代器模式比较正规的定义和类图(引用《大话设计模式》)如下所示:
2. 迭代器模式C++实现
这里交通工具检票为例实现迭代器模式。在这个例子中,抽象交通工具Traffic类对应上述类图中的Aggregate类,表示多元素对象,这里主要是遍历Traffic类中所有乘客是否买票。公交车和飞机是具体交通工具,对应类图中ConcreteAggregate类。抽象检票员类TicketCollector对应类图中的Iterator类,实现遍历操作;公交车检票员和飞机检票员是具体检票员,对应类图中的ConcreteIterator类。这里公交车检票员和飞机检票员的检查顺序不同,公交车检票员是从前往后检票,飞机检票员则是从后向前检票,主要为了说明遍历方式可以不同,所以使用了一个抽象Iterator类。
本人较懒,该例子的类图就不画了(《大话设计模式》没有),从上面的描述大家应该可以自己画出来了。
C++实现如下:
#include <iostream>
#include <memory>
#include <vector>
//******************Command Pattern************************
class TicketCollector;
//抽象交通工具类
class Traffic
{
private:
std::vector<std::string> passengers;//存储乘客姓名容器
public:
virtual std::shared_ptr<TicketCollector> CreateTickCollector() = 0;
virtual bool AddPassenger(const std::string& strPassengerName)
{
passengers.push_back(strPassengerName);
return true;
}
std::vector<std::string> GetPassengers() const
{
return passengers;
}
};
//抽象检票员类
class TicketCollector
{
public:
virtual std::string First() = 0;
virtual std::string Next() = 0;
virtual bool IsDone() = 0;
virtual std::string CurrentItem() = 0;
virtual ~TicketCollector() {}
};
//具体检票员类:公交车检票员,从前向后检票
class BusTicketCollector : public TicketCollector
{
private:
Traffic* smartBus;//要检查的交通工具
int current;
public:
BusTicketCollector(Traffic* pTraffic) : smartBus(pTraffic), current(0) { }
std::string First()
{
return smartBus->GetPassengers()[0];
}
std::string Next()
{
++current;
if (current < smartBus->GetPassengers().size())
{
return smartBus->GetPassengers()[current];
}
return "";
}
bool IsDone()
{
return current >= smartBus->GetPassengers().size() - 1 ? true : false;
}
std::string CurrentItem()
{
return smartBus->GetPassengers()[current];
}
};
//具体检票员类:飞机检票员,从后向前检票
class AirplaneTicketCollector : public TicketCollector
{
private:
Traffic* smartAirplane;//要检查的交通工具
int current;//
public:
AirplaneTicketCollector(Traffic* pTraffic) : smartAirplane(pTraffic)
{
current = pTraffic->GetPassengers().size() - 1;
}
std::string First()
{
return smartAirplane->GetPassengers()[current];
}
std::string Next()
{
--current;
if (current >= 0)
{
return smartAirplane->GetPassengers()[current];
}
return "";
}
bool IsDone()
{
return current <= 0 ? true : false;
}
std::string CurrentItem()
{
if (current < 0)
return "";
return smartAirplane->GetPassengers()[current];
}
};
//具体交通工具类: 公交车
class Bus : public Traffic
{
public:
std::shared_ptr<TicketCollector> CreateTickCollector()
{
return std::make_shared<BusTicketCollector>(this);
}
};
//具体交通工具类: 飞机
class Airplane : public Traffic
{
public:
std::shared_ptr<TicketCollector> CreateTickCollector()
{
return std::make_shared<AirplaneTicketCollector>(this);
}
};
//************************Test*****************************
int main()
{
std::shared_ptr<Traffic> traffic = std::make_shared<Bus>();
traffic->AddPassenger("大鸟");
traffic->AddPassenger("小菜");
traffic->AddPassenger("小美");
traffic->AddPassenger("小刚");
std::shared_ptr<TicketCollector> ticketCollector = traffic->CreateTickCollector();
std::cout << "公交车开始检票:" << std::endl;
std::cout << ticketCollector->First().c_str() << " 已买票!" << std::endl;
while (!ticketCollector->IsDone())
{
std::cout << ticketCollector->Next().c_str() << " 已买票!" << std::endl;
}
std::cout << "公交车检票完毕!\n" << std::endl;
traffic = std::make_shared<Airplane>();
traffic->AddPassenger("大鸟");
traffic->AddPassenger("小菜");
traffic->AddPassenger("小美");
traffic->AddPassenger("小刚");
ticketCollector = traffic->CreateTickCollector();
std::cout << "飞机开始检票:" << std::endl;
std::cout << ticketCollector->First().c_str() << " 已买票!" << std::endl;
while (!ticketCollector->IsDone())
{
std::cout << ticketCollector->Next().c_str() << " 已买票!" << std::endl;
}
std::cout << "飞机检票完毕!\n" << std::endl;
system("pause");
return 0;
}
总结
迭代器模式还是很好理解的,只要用过STL的同学应该都清楚原理,谢谢大家!
参考
《大话设计模式》