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