迭代器模式

 

迭代器模式(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 }
View Code

 

 

 

 

方式二

 

  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 }
View Code

 

posted @ 2017-01-09 11:07  _logan  阅读(120)  评论(0编辑  收藏  举报