24
05月
2020
迭代器模式
模式定义
迭代器模式(Iterator),又叫做游标(Cursor)模式。提供一种方法访问一个容器(Container)对象中各个元素,而又不需暴露该对象的内部细节。 当你需要访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑使用迭代器模式。另外,当需要对聚集有多种方式遍历时,可以考虑去使用迭代器模式。迭代器模式为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。
迭代器模式的优势
访问一个聚合对象的内容而无需暴露它的内部表示
支持对聚合对象的多种遍历
为遍历不同的聚合结构提供一个统一的接口
代码示例
Iterator\Book.class.php
<?php
namespace Iterator;
class Book
{
private $author;
private $title;
public function __construct($title, $author)
{
$this->title = $title;
$this->author = $author;
}
public function getAuthor()
{
return $this->author;
}
public function getTitle()
{
return $this->title;
}
public function getAuthorAndTitle()
{
return $this->getTitle() . ' by ' . $this->getAuthor();
}
}Iterator\BookList.class.php
<?php
namespace Iterator;
class BookList implements \Countable
{
private $books;
public function getBook($bookNumberToGet)
{
if(isset($this->books[$bookNumberToGet])) {
return $this->books[$bookNumberToGet];
}
return null;
}
public function addBook(Book $book)
{
$this->books[] = $book;
}
public function removeBook(Book $bookToRemove)
{
foreach ($this->books as $key => $book) {
if($book->getAuthorAndTitle() == $bookToRemove->getAuthorAndTitle()){
unset($this->books[$key]);
}
}
}
/**
* @inheritDoc
*/
public function count()
{
return $this->count($this->books);
}
}Iterator\BookListIterator.class.php
<?php
namespace Iterator;
class BookListIterator implements \Iterator
{
private $bookList;
protected $currentBook = 0;
public function __construct(BookList $bookList)
{
$this->bookList = $bookList;
}
/**
* @inheritDoc
*/
public function current()
{
return $this->bookList->getBook($this->currentBook);
}
/**
* @inheritDoc
*/
public function next()
{
$this->currentBook++;
}
/**
* @inheritDoc
*/
public function key()
{
return $this->currentBook;
}
/**
* @inheritDoc
*/
public function valid()
{
return null !== $this->bookList->getBook($this->currentBook);
}
/**
* @inheritDoc
*/
public function rewind()
{
$this->currentBook = 0;
}
}Iterator\IteratorTest.php
<?php
spl_autoload_register(function ($className){
$className = str_replace('\\', '/', $className);
include $className.".class.php";
});
use Iterator\Book;
use Iterator\BookList;
use Iterator\BookListIterator;
$bookList = new BookList();
$bookList->addBook(new Book('Learning PHP Design Patterns', 'William Sanders'));
$bookList->addBook(new Book('Professional Php Design Patterns', 'Aaron Saray'));
$bookList->addBook(new Book('Clean Code', 'Robert C. Martin'));
$iterator = new BookListIterator($bookList);
while ($iterator->valid()) {
echo $iterator->current()->getAuthorAndTitle() . "\n";
$iterator->next();
}测试示例:
php Iterator/IteratorTest.php 输出: Learning PHP Design Patterns by William Sanders Professional Php Design Patterns by Aaron Saray Clean Code by Robert C. Martin
总结
通过引入迭代器可以将数据的遍历功能从聚合对象中分离出来,聚合对象只负责存储数据,而遍历数据由迭代器来完成。
PHP标准库(SPL)中提供了迭代器接口 Iterator,要实现迭代器模式,实现该接口即可。
代码地址:https://github.com/798256478/design-patterns/tree/master/Iterator