diff --git a/Behavioral/Iterator/Book.php b/Behavioral/Iterator/Book.php
new file mode 100644
index 0000000..a0d1114
--- /dev/null
+++ b/Behavioral/Iterator/Book.php
@@ -0,0 +1,32 @@
+author = $author;
+ $this->title = $title;
+ }
+
+ public function getAuthor()
+ {
+ return $this->author;
+ }
+
+ public function getTitle()
+ {
+ return $this->title;
+ }
+
+ public function getAuthorAndTitle()
+ {
+ return $this->getTitle() . ' by ' . $this->getAuthor();
+ }
+}
diff --git a/Behavioral/Iterator/BookList.php b/Behavioral/Iterator/BookList.php
new file mode 100644
index 0000000..eb9a8be
--- /dev/null
+++ b/Behavioral/Iterator/BookList.php
@@ -0,0 +1,42 @@
+count()) {
+ return $this->books[$bookNumberToGet];
+ }
+
+ return NULL;
+ }
+
+ public function addBook(Book $book)
+ {
+ $this->books[] = $book;
+
+ return $this->count();
+ }
+
+ public function removeBook(Book $bookToRemove)
+ {
+ foreach ($this as $key => $book) {
+ /** @var Book $book */
+ if ($book->getAuthorAndTitle() === $bookToRemove->getAuthorAndTitle()) {
+ unset($this->books[$key]);
+ }
+ }
+
+ return $this->count();
+ }
+
+ public function count()
+ {
+ return count($this->books);
+ }
+}
diff --git a/Behavioral/Iterator/BookListIterator.php b/Behavioral/Iterator/BookListIterator.php
new file mode 100644
index 0000000..d0992c6
--- /dev/null
+++ b/Behavioral/Iterator/BookListIterator.php
@@ -0,0 +1,77 @@
+bookList = $bookList;
+ }
+
+ /**
+ * Return the current book
+ * @link http://php.net/manual/en/iterator.current.php
+ * @return Book Can return any type.
+ */
+ public function current()
+ {
+ return $this->bookList->getBook($this->currentBook);
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Move forward to next element
+ * @link http://php.net/manual/en/iterator.next.php
+ * @return void Any returned value is ignored.
+ */
+ public function next()
+ {
+ $this->currentBook++;
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Return the key of the current element
+ * @link http://php.net/manual/en/iterator.key.php
+ * @return mixed scalar on success, or null on failure.
+ */
+ public function key()
+ {
+ return $this->currentBook;
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Checks if current position is valid
+ * @link http://php.net/manual/en/iterator.valid.php
+ * @return boolean The return value will be casted to boolean and then evaluated.
+ * Returns true on success or false on failure.
+ */
+ public function valid()
+ {
+ return $this->currentBook < $this->bookList->count();
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Rewind the Iterator to the first element
+ * @link http://php.net/manual/en/iterator.rewind.php
+ * @return void Any returned value is ignored.
+ */
+ public function rewind()
+ {
+ $this->currentBook = 0;
+ }
+}
\ No newline at end of file
diff --git a/Behavioral/Iterator/BookListReverseIterator.php b/Behavioral/Iterator/BookListReverseIterator.php
new file mode 100644
index 0000000..2e38f63
--- /dev/null
+++ b/Behavioral/Iterator/BookListReverseIterator.php
@@ -0,0 +1,23 @@
+bookList = $bookList;
+ $this->currentBook = $this->bookList->count() - 1;
+ }
+
+ public function next()
+ {
+ $this->currentBook--;
+ }
+
+ public function valid()
+ {
+ return 0 <= $this->currentBook;
+ }
+}
\ No newline at end of file
diff --git a/Behavioral/Iterator/File.php b/Behavioral/Iterator/File.php
deleted file mode 100644
index e2e6a3d..0000000
--- a/Behavioral/Iterator/File.php
+++ /dev/null
@@ -1,39 +0,0 @@
-rowSet = new Rowset($this);
- }
-
- /**
- * processes the rowSet
- */
- public function process()
- {
- // this is the place to show how using an iterator, with foreach
- // See the CardGame.php file
- $this->rowSet->process();
- }
-}
diff --git a/Behavioral/Iterator/Row.php b/Behavioral/Iterator/Row.php
deleted file mode 100644
index df4002d..0000000
--- a/Behavioral/Iterator/Row.php
+++ /dev/null
@@ -1,27 +0,0 @@
-data = $data;
- }
-
- /**
- * {@inheritdoc}
- */
- public function process()
- {
- // do some fancy things here ...
- }
-}
diff --git a/Behavioral/Iterator/RowSet.php b/Behavioral/Iterator/RowSet.php
deleted file mode 100644
index f1ef5d7..0000000
--- a/Behavioral/Iterator/RowSet.php
+++ /dev/null
@@ -1,100 +0,0 @@
-file = $file;
- }
-
- /**
- * composite pattern: run through all rows and process them
- *
- * @return void
- */
- public function process()
- {
- // this actually calls rewind(), { next(), valid(), key() and current() :}
- /**
- * THE key feature of the Iterator Pattern is to provide a *public contract*
- * to iterate on a collection without knowing how items are handled inside
- * the collection. It is not just an easy way to use "foreach"
- *
- * One cannot see the point of iterator pattern if you iterate on $this.
- * This example is unclear and mixed with some Composite pattern ideas.
- */
- foreach ($this as $line => $row) {
- $row->process();
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function rewind()
- {
- // seek to first line from $this->file
- }
-
- /**
- * {@inheritdoc}
- */
- public function next()
- {
- // read the next line from $this->file
- if (!$eof) {
- $data = ''; // get the line
- $this->currentRow = new Row($data);
- } else {
- $this->currentRow = null;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function current()
- {
- return $this->currentRow;
- }
-
- /**
- * {@inheritdoc}
- */
- public function valid()
- {
- return null !== $this->currentRow;
- }
-
- /**
- * {@inheritdoc}
- */
- public function key()
- {
- // you would want to increment this in next() or whatsoever
- return $this->lineNumber;
- }
-}
diff --git a/Behavioral/Iterator/Tests/IteratorTest.php b/Behavioral/Iterator/Tests/IteratorTest.php
new file mode 100644
index 0000000..4bc58f0
--- /dev/null
+++ b/Behavioral/Iterator/Tests/IteratorTest.php
@@ -0,0 +1,66 @@
+bookList = new BookList();
+ $this->bookList->addBook(new Book('Learning PHP Design Patterns', 'William Sanders'));
+ $this->bookList->addBook(new Book('Professional Php Design Patterns', 'Aaron Saray'));
+ $this->bookList->addBook(new Book('Clean Code', 'Robert C. Martin'));
+ }
+
+ public function expectedAuthors()
+ {
+ return array(
+ array(
+ array(
+ 'Learning PHP Design Patterns by William Sanders',
+ 'Professional Php Design Patterns by Aaron Saray',
+ 'Clean Code by Robert C. Martin'
+ )
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider expectedAuthors
+ */
+ public function testUseAIteratorAndValidateAuthors($expected)
+ {
+ $iterator = new BookListIterator($this->bookList);
+
+ while ($iterator->valid()) {
+ $expectedBook = array_shift($expected);
+ $this->assertEquals($expectedBook, $iterator->current()->getAuthorAndTitle());
+ $iterator->next();
+ }
+ }
+
+ /**
+ * @dataProvider expectedAuthors
+ */
+ public function testUseAReverseIteratorAndValidateAuthors($expected)
+ {
+ $iterator = new BookListReverseIterator($this->bookList);
+
+ while ($iterator->valid()) {
+ $expectedBook = array_pop($expected);
+ $this->assertEquals($expectedBook, $iterator->current()->getAuthorAndTitle());
+ $iterator->next();
+ }
+ }
+}
\ No newline at end of file