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