迭代器模式c++实现
Posted 今天也要努力搬砖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器模式c++实现相关的知识,希望对你有一定的参考价值。
参考书籍《Head First设计模式》
需求场景
餐馆和咖啡馆的菜单分别是用数组和容器(vector)存储的,有一天餐馆和咖啡店合并了想要打印菜单,必须实现两个不同的遍历(数组用sizeof计算长度,用[]取元素;容器用size取长度,用at()取元素),来处理两种不同的聚合类型,代码类似于下面所示
for (int i = 0; i<sizeof(dinerMenu.items_) / sizeof(dinerMenu.items_[0]); i++)
MenuItem item = dinerMenu.items_[i];
std::cout << item.name <<","<< item.description << ","<< item.price << std::endl;
for (int i = 0; i<conffeMenu.items_.size(); i++)
MenuItem item = conffeMenu.items_.at(i);
std::cout << item.name << "," << item.description << "," << item.price <<std::endl;
如果我们还要遍历另外一种聚合数据,比如map,那么就要再加一种遍历方法。又或者我们有一天咖啡店不用容器存储,改用数组了,那我们的遍历方法又要改写。这就要求客户端对聚合的实现很了解,即针对实现编程(而我们提倡的设计原则是针对接口编程,而不是针对实现编程)。
在上述例子中引起变化的是:由不同的组合类型所造成的遍历。那我们可以封装遍历吗?迭代器模式就是封装了遍历。迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
模式定义
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露其内部表示。
类图如下
代码实现
如上面需求场景中,我们使用迭代器模式,让两个具体的聚合类(餐馆和咖啡馆)都提供一个createIterator的接口,客户端使用该接口返回的iterator遍历聚合体中各元素。这样客户端不需要关系聚合体的具体实现,针对不同聚合体提供的iterator使用方法一样。
先定义迭代器接口(抽象类Iterator)
class Iterator
public:
virtual bool hasNext() = 0;
virtual void* next() = 0;
;
两个具体的迭代器:餐厅菜单迭代器和咖啡店菜单迭代器
class CoffeMenuIterator :public Iterator
public:
CoffeMenuIterator(std::vector< MenuItem>* items) :items_(items), position_(0)
virtual MenuItem& next()override
MenuItem& item = items_->at(position_);
position_++;
return item;
bool hasNext()override
if (position_ >= items_->size())
return false;
else
return true;
private:
std::vector< MenuItem>* items_;
int position_;
;
class DinerMenuIterator :public Iterator
public:
DinerMenuIterator(MenuItem items[],int length) :items_(items), position_(0),length_(length)
virtual MenuItem& next()override
MenuItem& item = items_[position_];
position_++;
return item;
bool hasNext()override
if (position_ >= length_)
return false;
else
return true;
private:
MenuItem* items_;
int position_;
int length_;
;
再实现两个具体的聚合类,针对该例子即实现餐馆菜单和咖啡店菜单(它们都要实现createIterator接口)。
class Menu
public:
virtual Iterator* createIterator() = 0;
;
class DinerMenu :public Menu
public:
DinerMenu()
items_[0] = "红烧肉","红烧肉,肥瘦相间,香而不腻",32 ;
items_[1] = "西红柿炒鸡蛋","西红柿炒鸡蛋,国民妈妈菜",15 ;
items_[2] = "土豆丝","土豆丝,超便宜",12 ;
virtual Iterator* createIterator() override
return new DinerMenuIterator(items_,3);
private:
MenuItem items_[3];
;
class CoffeMenu :public Menu
public:
CoffeMenu()
items_.push_back( "拿铁","拿铁,好喝",18 );
items_.push_back( "卡布奇诺","卡布奇诺卡布奇诺",18 );
items_.push_back( "意式浓缩咖啡","意式浓缩咖啡",22 );
virtual Iterator* createIterator() override
return new CoffeMenuIterator(&items_);
private:
std::vector< MenuItem> items_;
;
运行测试效果如下
以上是关于迭代器模式c++实现的主要内容,如果未能解决你的问题,请参考以下文章