Iteratorパターン

完全にデザインパターンを忘れているので、復習を兼ねて1通りやっていこうと思う。手元ではJava言語で学ぶデザインパターン入門を見ながらやっている。


というわけで、今回はIteratorパターン。
Iterator パターン - Wikipedia
だいたいどの言語でも実装されているのであまり使う機会がないけど一応。


継承を使わないで書くと

#include <string>
#include <iostream>
using namespace std;
//Simple Object
class Book
{
public :
	Book(){}
	Book(string name){this->name_ = name;}
	string GetName(){return this->name_;}
private :
	string name_;
};
//Aggregate & Iterator
template <class T> class Iterator;
template <class T>
class Aggregate
{
public :
	Aggregate(int size) : current_(0){
		items_ = new T[size];
	}
	virtual ~Aggregate(){
		delete [] items_;
	}
	Iterator<T> CreateIterator() const{return Iterator<T>(*this);}
	void Add(const T& item){
		items_[current_] = item;
        current_++;
	}
	const T& GetAt(int index) const{
		return items_[index];
	}
	int GetSize() const{return current_;}
private :
	T * items_;
	int current_;
};

template<class T>
class Iterator
{
public :	
	Iterator(const Aggregate<T>& aggregate) : aggregate_(&aggregate), pointer_(0){}
	virtual ~Iterator(){}
	const T& Next(){
		return aggregate_->GetAt(pointer_++);
	}
	bool HasNext(){
		return pointer_ < aggregate_->GetSize();
	}
private :
	const Aggregate<T> *aggregate_;
	int pointer_;
};
//main function
int main()
{
	Aggregate<Book> book_aggregate = Aggregate<Book>(3);
	book_aggregate.Add(Book("R cookbook"));
	book_aggregate.Add(Book("code complete"));
	book_aggregate.Add(Book("stochastic calculus"));
	Iterator<Book> it = book_aggregate.CreateIterator();
	while(it.HasNext()){
		Book book = it.Next();
		cout << "Book name : " << book.GetName() << endl;
	}
	getchar();
	return 0;
}

こんな感じになる。上述の本にできるだけ忠実に書くと

#include <string>
#include <iostream>
using namespace std;

//Aggregate & Iterator
template<class T>
class Iterator
{
public :	
	virtual ~Iterator(){}
	virtual const T& Next() = 0;
	virtual bool HasNext() = 0;
};
template <class T>
class Aggregate
{
public :
	virtual ~Aggregate(){}
	virtual Iterator<T> * CreateIterator() const = 0;
private :
};

//Book type classes
class BookShelf;
class Book
{
public :
	Book(){}
	Book(string name){this->name_ = name;}
	string GetName(){return this->name_;}
private :
	string name_;
};
class BookShelfIterator : public Iterator<Book>
{
public :
	BookShelfIterator(const BookShelf& aggregate) : book_shelf_(&aggregate), pointer_(0){};
	~BookShelfIterator(){}
	const Book& Next();
	bool HasNext();
private :
	const BookShelf *book_shelf_;
	int pointer_;
};
class BookShelf : public Aggregate<Book>
{
public :
	BookShelf(int size);
	virtual ~BookShelf();
	Iterator<Book> * CreateIterator() const;
	void Add(const Book& item);
	const Book & GetAt(int index) const;
	int GetSize() const;
private :
	Book * items_;
	int current_;
};
const Book& BookShelfIterator::Next()
{
	return book_shelf_->GetAt(pointer_++);
}
bool BookShelfIterator::HasNext(){
	return pointer_ < book_shelf_->GetSize();
}
BookShelf::BookShelf(int size) : current_(0){
	items_ = new Book[size];
}
BookShelf::~BookShelf(){
	delete [] items_;
}
Iterator<Book> * BookShelf::CreateIterator() const
{
	return new BookShelfIterator(*this);
}
void BookShelf::Add(const Book& item){
	items_[current_] = item;
	current_++;
}
const Book & BookShelf::GetAt(int index) const{
	return items_[index];
}
int BookShelf::GetSize() const
{
	return current_;
}


//main function
int main()
{
	BookShelf book_shelf = BookShelf(3);
	book_shelf.Add(Book("R cookbook"));
	book_shelf.Add(Book("code complete"));
	book_shelf.Add(Book("stochastic calculus"));
	Iterator<Book> *it = book_shelf.CreateIterator();
	while(it->HasNext()){
		Book book = it->Next();
		cout << "Book name : " << book.GetName() << endl;
	}
	delete it;
	getchar();
	return 0;
}

な感じかな。JAVAと違ってObjectクラスのようなものがないのでちょいと冗長。