迭代器模式
迭代器模式(Iterator),又叫做游标(Cursor)模式。提供一种方法访问一个容器(Container)对象中各个元素,而又不需暴露该对象的内部细节。 PHP标准库(SPL)中提供了迭代器接口 Iterator,要实现迭代器模式,实现该接口即可。
这个模式有两种实现的方式
方式一
1 <?php 2 3 class Book 4 { 5 private $_author; 6 private $_title; 7 8 public function __construct($title, $author) 9 { 10 $this->_author = $author; 11 $this->_title = $title; 12 } 13 14 public function getAuthor() 15 { 16 return $this->_author; 17 } 18 19 public function getTitle() 20 { 21 return $this->_title; 22 } 23 24 public function getAuthorAndTitle() 25 { 26 return $this->getTitle().' by '.$this->getAuthor(); 27 } 28 } 29 30 31 class BookList implements \Countable, \Iterator 32 { 33 private $_books = []; 34 private $_currentIndex = 0; 35 36 37 public function addBook(Book $book) 38 { 39 $this->_books[] = $book; 40 } 41 42 public function removeBook(Book $bookToRemove) 43 { 44 foreach ($this->_books as $key => $book) { 45 if ($book->getAuthorAndTitle() === $bookToRemove->getAuthorAndTitle()) { 46 unset($this->_books[$key]); 47 } 48 } 49 50 $this->_books = array_values($this->_books); 51 } 52 53 54 55 /* 以下是接口部分 */ 56 57 public function count() 58 { 59 return count($this->_books); 60 } 61 62 public function current() 63 { 64 return $this->_books[$this->_currentIndex]; 65 } 66 67 public function key() 68 { 69 return $this->_currentIndex; 70 } 71 72 public function next() 73 { 74 $this->_currentIndex++; 75 } 76 77 public function rewind() 78 { 79 $this->_currentIndex = 0; 80 } 81 82 public function valid() 83 { 84 return isset($this->_books[$this->_currentIndex]); 85 } 86 } 87 88 89 90 91 $bookList = new BookList(); 92 $bookList->addBook(new Book('Learning PHP Design Patterns', 'William Sanders')); 93 $bookList->addBook(new Book('Professional Php Design Patterns', 'Aaron Saray')); 94 $bookList->addBook(new Book('Clean Code', 'Robert C. Martin')); 95 96 foreach ($bookList as $book) { 97 echo "<br/>"; 98 echo $book->getAuthorAndTitle(); 99 }
方式二
1 <?php 2 3 4 class Book 5 { 6 private $_author; 7 private $_title; 8 9 public function __construct($title, $author) 10 { 11 $this->_author = $author; 12 $this->_title = $title; 13 } 14 15 public function getAuthor() 16 { 17 return $this->_author; 18 } 19 20 public function getTitle() 21 { 22 return $this->_title; 23 } 24 25 public function getAuthorAndTitle() 26 { 27 return $this->getTitle() . ' by ' . $this->getAuthor(); 28 } 29 } 30 31 32 class BookList implements \Countable 33 { 34 private $_books; 35 36 public function getBook($bookNumberToGet) 37 { 38 if (isset($this->_books[$bookNumberToGet])) { 39 return $this->_books[$bookNumberToGet]; 40 } 41 42 return null; 43 } 44 45 public function addBook(Book $book) 46 { 47 $this->_books[] = $book; 48 } 49 50 public function removeBook(Book $bookToRemove) 51 { 52 foreach ($this->_books as $key => $book) { 53 if ($book->getAuthorAndTitle() === $bookToRemove->getAuthorAndTitle()) { 54 unset($this->_books[$key]); 55 } 56 } 57 } 58 59 public function count() 60 { 61 return count($this->_books); 62 } 63 } 64 65 66 class BookListIterator implements \Iterator 67 { 68 private $_bookList; 69 protected $_currentBook = 0; 70 71 public function __construct(BookList $bookList) 72 { 73 $this->_bookList = $bookList; 74 } 75 76 /** 77 * Return the current book 78 * @link http://php.net/manual/en/iterator.current.php 79 * @return Book Can return any type. 80 */ 81 public function current() 82 { 83 return $this->_bookList->getBook($this->_currentBook); 84 } 85 86 /** 87 * Move forward to next element 88 * @link http://php.net/manual/en/iterator.next.php 89 * @return void Any returned value is ignored. 90 */ 91 public function next() 92 { 93 $this->_currentBook++; 94 } 95 96 /** 97 * Return the key of the current element 98 * @link http://php.net/manual/en/iterator.key.php 99 * @return mixed scalar on success, or null on failure. 100 */ 101 public function key() 102 { 103 return $this->_currentBook; 104 } 105 106 /** 107 * Checks if current position is valid 108 * @link http://php.net/manual/en/iterator.valid.php 109 * @return boolean The return value will be casted to boolean and then evaluated. 110 * Returns true on success or false on failure. 111 */ 112 public function valid() 113 { 114 return null !== $this->_bookList->getBook($this->_currentBook); 115 } 116 117 /** 118 * Rewind the Iterator to the first element 119 * @link http://php.net/manual/en/iterator.rewind.php 120 * @return void Any returned value is ignored. 121 */ 122 public function rewind() 123 { 124 $this->_currentBook = 0; 125 } 126 } 127 128 129 130 131 132 133 134 $bookList = new BookList(); 135 $bookList->addBook(new Book('Learning PHP Design Patterns', 'William Sanders')); 136 $bookList->addBook(new Book('Professional Php Design Patterns', 'Aaron Saray')); 137 $bookList->addBook(new Book('Clean Code', 'Robert C. Martin')); 138 139 $iterator = new BookListIterator($bookList); 140 141 while ($iterator->valid()) { 142 print "<br/>"; 143 print $iterator->current()->getAuthorAndTitle(); 144 $iterator->next(); 145 }