HomePHP Page 2 - Introducing Visitor Objects in PHP 5
An introductory example - PHP
Although the article’s title may seem a bit intimidating, the truth is that things are much simpler than you think. Like many other programming languages, PHP also allows you to construct and use visitor objects with minor hassles. But, before I go deeper into the subject, first let’s ask ourselves the following question: what are visitor objects, after all?
I strongly believe that seemingly-complex topics are best understood by simple methods, so I'm going to introduce a very manageable example of how to create and use visitor objects in PHP 5.
My plan basically consists of developing a couple of simple classes, which store generic information in arrays and text files. Once these classes have been defined and correctly understood, I'll use a few visitor objects to obtain basic information about the classes in question.
Thus, I'll begin defining a generic abstract "VisitedData" class, and then derive two subclasses. As I mentioned before, here is the signature of the first abstract class:
// define abstract 'VisitedData' abstract class VisitedData{ abstract function acceptVisitator(Visitator $visitator); }
As you can appreciate, the class shown above implements a generic structure for creating objects that will be visited by the respective visitor objects. Regarding this concept, you can see that this class presents an abstract "acceptVisitator()" method, which will be the entry point for accepting visitor objects.
Now, having defined the previous abstract class, let me show you the pair of sub classes that implement the method listed above. First of all, here is the definition of the "VisitedArray" class:
// extend 'VisitedArray' class from abstract 'VisitedData' class class VisitedArray extends VisitedData{ private $elements=array(); public function __construct(){} // add new element to array public function addElement($element){ if(!$element){ throw new Exception('Invalid array element'); } $this->elements[]=$element; } // get array size public function getSize(){ if(!$size=count($this->elements)){ throw new Exception('Error counting array elements'); } return $size; } // accepts 'visitator' object and call 'visitArray()' method public function acceptVisitator(Visitator $visitator){ $visitator->visitArray($this); } }
In this case, the above child class perform some basic tasks, like storing plain strings in the predefined "elements" array. However, I strongly recommend that you focus your attention on the "acceptVisitator()" method, since it's the most relevant one with reference to implementing the visitor pattern.
Please, notice how this method accepts a visitor object, which uses the "visitArray()" method, to obtain information about the visited object. This schema is extremely common when using the visitor pattern, thus you should keep it in mind for further reference: in all cases, the visited object is passed as a parameter to the respective visitor, in order to get additional information about it.
Now, do you see how a visitor object uses its own method for retrieving relevant data about the visited one? That's exactly the expected behavior of objects when using the visitor pattern! Again, try to bear this interaction schema in mind, since in most cases it will be nearly the same.
So far, I showed you how to write an array manipulation class that accepts a visitor object. However, I'd like to extend the prior example and create another sample class, which also takes up a visitor, and specifically saves data to a given text file.
In the upcoming section, I'll define the structure of this brand new class, therefore go ahead and read the next few lines. It'll be really instructive, trust me.