PHP design pattern: Iterator pattern
Concept
The Iterator mode is also called the Cursor mode. Provides a method to access various elements of an aggregate object sequentially without exposing the internal representation of the object.
When you need to access an aggregate object and traverse all these objects, you should consider using the iterator mode. In addition, you can consider using the iterator mode when multiple aggregation methods are required. The iterator mode provides unified interfaces for traversing different clustering structures, such as start, next, end, and current.
Applicable scenarios
Access the content of an aggregate object without exposing its internal representation
Supports multiple traversal of aggregate objects
Provides a unified interface for traversing different aggregation structures
UML diagram
Role
Iterator: the Iterator defines the interface for accessing and traversing elements.
ConcreteIterator (specific iterator): the iterator implements the iterator interface to track the current position of the aggregation time.
Aggregate (aggregation): aggregation defines the interface for creating the corresponding iterator object
ConcreteAggregate (specific aggregation): The specific aggregation implementation creates the corresponding iterator interface, this operation returns a proper instance of ConcreteIterator
Code
The code is as follows:
Php spl provides the Iterator interface and container interface IteatorAggragate. the source code is as follows:
/** * Interface to detect if a class is traversable using &foreach;. * @link http://php.net/manual/en/class.traversable.php */interface Traversable {}/** * Interface to create an external Iterator. * @link http://php.net/manual/en/class.iteratoraggregate.php */interface IteratorAggregate extends Traversable { /** * Retrieve an external iterator * @link http://php.net/manual/en/iteratoraggregate.getiterator.php * @return Traversable An instance of an object implementing Iterator or * Traversable * @since 5.0.0 */ public function getIterator();}/** * Interface for external iterators or objects that can be iterated * themselves internally. * @link http://php.net/manual/en/class.iterator.php */interface Iterator extends Traversable { /** * Return the current element * @link http://php.net/manual/en/iterator.current.php * @return mixed Can return any type. * @since 5.0.0 */ public function current(); /** * Move forward to next element * @link http://php.net/manual/en/iterator.next.php * @return void Any returned value is ignored. * @since 5.0.0 */ public function next(); /** * 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. * @since 5.0.0 */ public function key(); /** * 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. * @since 5.0.0 */ public function valid(); /** * Rewind the Iterator to the first element * @link http://php.net/manual/en/iterator.rewind.php * @return void Any returned value is ignored. * @since 5.0.0 */ public function rewind();}
Here we directly implement the above two interfaces. please refer to the following code:
Array = $ array; $ this-> position = 0;} function rewind () {$ this-> position = 0;} function current () {return $ this-> array [$ this-> position];} function key () {return $ this-> position;} function next () {++ $ this-> position;} function valid () {return isset ($ this-> array [$ this-> position]);} /*** Class MyAggregate aggregation container */class ConcreteAggregate implements IteratorAggregate {public $ property;/*** add attribute ** @ param $ property */public function addProperty ($ property) {$ this-> property [] = $ property;} public function getIterator () {return new ConcreteIterator ($ this-> property );}} /*** test the Class Client */class Client {public static function test () {// Create a container $ concreteAggregate = new ConcreteAggregate (); // add attributes $ concreteAggregate-> addProperty ('property 1'); // add attributes $ concreteAggregate-> addProperty ('property 2 '); // Create an iterator for the container $ iterator = $ concreteAggregate-> getIterator (); // traverse while ($ iterator-> valid ()) {$ key = $ iterator-> key (); $ value = $ iterator-> current (); echo 'key :'. $ key. 'value :'. $ value. ''; $ iterator-> next () ;}} Client: test ();
Running result:
Key: 0 value: Attribute 1
Key: 1 value: Attribute 2