迭代器模式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++实现的主要内容,如果未能解决你的问题,请参考以下文章

迭代器模式c++实现

设计模式--迭代器模式C++实现

深入浅出设计模式之模板方法模式迭代器模式组合模式

C++ 迭代器iterator的实现原理

Headfirst设计模式的C++实现——迭代器(Iterator)

Headfirst设计模式的C++实现——迭代器(Iterator)改良版