Expanding the Application Range of Visitor Objects in PHP 5

Has your career as PHP developer led you to learn more about the most popular design patterns? If it has, then this series may help you get a better grounding in them. Welcome to the second installment of the series “Introducing Visitor Objects in PHP 5.” Made up of three articles, this series introduces the key points of how to apply the visitor pattern in PHP, and emphasizes the practical side of the topic by walking you though copious hands-on examples.

Introduction

If the word “visitor” doesn’t ring any bells to you, let me tell you quickly what it means in the context of pattern-based programming. Essentially, a visitor object is one that’s passed in straightly to another by a specific method, in order to inspect its properties and retrieve relevant information about this visited object.

Since at first glance the theory about visitors can be sometimes pretty overwhelming, in the first tutorial of the series, I introduced an easy-to-follow example, which hopefully demonstrated by a friendly approach how to create visitors with PHP 5. The example in question showed how two data handling classes could be visited by a single visitor object, in order to obtain concrete data about them, without the need to invoke specifically any of its accessing methods.

Although the example shown in the previous article may not fit all the needs of a real-world application, I think that one of the most important things here consists of understanding the primary logic behind constructing visitor objects, and then, when the pattern has been appropriately mastered, it can be used in more realistic situations.

Well, at this stage I’m assuming that creating visitor objects with PHP isn’t a strange concept to you any longer, therefore I’ll continue this journey by developing some additional -yet useful- examples on how to build up and implement visitors with PHP 5. The main purpose of this is simply reaffirming the concepts deployed in the first tutorial, so you can have a solid background for including your own visitor classes inside your PHP applications.

With the preliminaries out of our way, let’s move on and continue learning more examples on how to use the visitor pattern in PHP. Let’s go!

{mospagebreak title=Visiting users isn’t a bad idea after all: setting up a new practical example}

The visitor pattern (among others) reveals its real power when it’s presented within the environment of a practical situation. Therefore I’m going to set up another example which will illustrate yet another case where this pattern can be applied.

To begin with, I’ll define a highly generic “User” class, and next create a sub class from it. This child class will expose a concrete method that will allow a visitor object to inspect and obtain all its visible properties in only one step. Sounds quite good, right? Considering this propitious scenario, take a look at the abstract class defined below, which represents the generic model of a hypothetical user:

// define abstract class ‘User’
abstract class User{
    private $userID;
    private $firstName;
    private $lastName;
    private $postalAddress;
    private $email;
    abstract function setUserID($userID);
    abstract function setFirstName($firstName);
    abstract function setLastName($lastName);
    abstract function setPostalAddress($postalAddress);
    abstract function setEmail($email);
    abstract function getUserID();
    abstract function getFirstName();
    abstract function getLastName();
    abstract function getPostalAddress();
    abstract function getEmail();
    abstract function acceptVisitor(Visitor $visitor);
}

As you can appreciate, above I created a generic model of a typical user. The class also has some abstract methods, which are handy for accessing and retrieving the properties of this user, such as First Name, Last Name, Postal Address and so forth. Of course, aside from the regular accessors and modifiers, there’s one method that deserves special attention. It is the “acceptVisitor()” method, which will be responsible for accepting a visitor, in order to inspect all the properties that belongs to the visited object.

Now that I have shown you the generic structure of the “User” class, I’ll derive a child class from it which implements concretely all the abstract methods declared before.

Of course, all these tasks will be performed over the course of the next section, thus keep reading to learn how this will be achieved.

{mospagebreak title=Deriving a subclass from the User base class: creating sets of software user objects}

As I said before, after defining the overall structure of the “User” class, I’ll derive a subclass from it to implement concretely all its abstract methods. In this case, because I’m usually inclined to work with software packages, the child class that I plan to derive will be called “SoftwareUser.”

Please look at the signature of this new class:

//define concrete ‘SoftwareUser’ class (extends User class)
class SoftwareUser extends User{
    private $software;
    // set user ID
    public function setUserID($userID){
        if(!userID||!is_int($userID)||$userID<0){
            throw new Exception(‘Invalid userID!’);
        }
        $this->userID=$userID;
    }
    // get user ID
    public function getUserID(){
        return $this->userID;
    }
    // set user’s first Name
    public function setFirstName($firstName){
        if(!$firstName||strlen($firstName)<4||strlen($firstName)
>32){
            throw new Exception(‘Invalid First Name (it must be a
string between 8 and 32 characters long.)’);
        }
        $this->firstName=$firstName;
    }
    // get user’s first Name
    public function getFirstName(){
        return $this->firstName;
    }
    // set user’s last name
    public function setLastName($lastName){
        if(!$lastName||strlen($lastName)<4||strlen($lastName)>32)
{
            throw new Exception(‘Invalid Last Name (it must be a
string between 4 and 32 characters long.)’);
        }
        $this->lastName=$lastName;
    }
    // get user’s Last Name
    public function getLastName(){
        return $this->lastName;
    }
    // set user’s postal address
    public function setPostalAddress($postalAddress){
        if(!$postalAddress||strlen($postalAddress)<8||strlen
($postalAddress)>64){
            throw new Exception(‘Invalid Postal Address (it must
be a string between 4 and 64 characters long.)’);
        }
        $this->postalAddress=$postalAddress;
    }
    // get user’s postal address
    public function getPostalAddress(){
        return $this->postalAddress;
    }
    // set user’s email
    public function setEmail($email){
        if(!$email||!preg_match(“/.+@.+..+./”,$email)||!
checkdnsrr(array_pop(explode(“@”,$email)),”MX”)){
            throw new Exception(‘Invalid Email Address’);
        }
        $this->email=$email;
    }
    // get user’s email address
    public function getEmail(){
        return $this->email;
    }
    // set user’s preferred software
    public function setPreferredSoftware($software){
        if(!$software){
            throw new Exception(‘Invalid software name’);
        }
        $this->software=$software;
    }
    // get user’s preferred software
    public function getPreferredSoftware(){
        return $this->software;
    }
    // accept visitor
    public function acceptVisitor(Visitor $visitor){
        $visitor->visitSoftwareUser($this);
    }
}

As illustrated above, the “SoftwareUser” class now offers a concrete implementation for all the abstract methods that were defined originally inside the base class. Nevertheless, aside from looking into the set of accessors and modifiers, I want you to pay attention to the following method:

public function acceptVisitor(Visitor $visitor){
    $visitor->visitSoftwareUser($this);
}

If you recall the concepts deployed in the first article, then you’ll realize that the above method applies a nearly identical implementation to the examples shown in that particular tutorial to accept a visitor object. This schema will be almost the same each time you need to code a visited class, therefore I recommend that you keep it fresh in your mind.

So far, I demonstrated how to create a “SoftwareUser” class which is provided with the ability to accept a visitor object which will eventually inspect the pertinent properties. However, things get really exciting when coding the respective visitor class.

I’m pretty sure that you want to see how this class will look, therefore click on the link that appears below and keep learning more.

{mospagebreak title=Visiting software users isn’t boring at all: creating a concrete visitor class}

It’s quite possible that you’re wondering how a visitor class can be coded to allow all its properties to be retrieved without having to use its accessing methods. Well, fortunately your question can be answered in two easy steps: first, I’ll define the generic structure of a visitor class, and then I’ll create a subclass from it.

Indeed, this sounds logical, thus in accordance with this approach, below I listed the signature of the abstract “Visitor” class:

// define abstract ‘Visitor’ class
abstract class Visitor{
    abstract function visitSoftwareUser(SoftwareUser $softwareUser);
} 

That’s all I need to define the generic model of a visitor. Notice the declaration of the abstract “visitSoftwareUser()” method, which will accept as input argument the visited object, in this case represented by an instance of the “SoftwareUser” class.

Now that you know how the prior abstract class looks, it’s time to implement its visiting method. That said, here is the corresponding definition of the entirely new “SoftwareUserVisitor” subclass:

// define concrete ‘SoftwareUserVisitor’ class
class SoftwareUserVisitor extends Visitor{
    private $softwareUserInfo=array();
    // obtain user information as array
    public function visitSoftwareUser(SoftwareUser $softwareUser){
        $this->softwareUserInfo['userid']=$softwareUser-
>getUserID();
        $this->softwareUserInfo['firstname']=$softwareUser-
>getFirstName();
        $this->softwareUserInfo['lastname']=$softwareUser-
>getLastName();
        $this->softwareUserInfo['postaladdress']=$softwareUser-
>getPostalAddress();
        //$this->softwareUserInfo['email']=$softwareUser-
>getEmail();
        $this->softwareUserInfo['software']=$softwareUser-
>getPreferredSoftware();
    }
    public function getSoftwareUserInfo(){
        return $this->softwareUserInfo;
    }
} 

As you can see, now this brand new class offers a concrete implementation for its “visitSoftwareUser()” method. It’s clear to see here how all the properties of an object of type “SoftwareUser” are retrieved by the visitor in question, and additionally, to make things even easier, they’re stored in an array. Short and understandable!

At this level, after defining the two classes that allow the implementation of the visitor pattern, that is, the visited and visitor classes respectively, it’s a good time to watch them together in action.

Not surprisingly, that’s exactly the subject that I’ll cover in the next few lines. Keep reading; I’ll be waiting for you in the following section.

{mospagebreak title=Putting the classes to work together: seeing the visitor object in action}

In order to see how the two classes defined before can establish a mutual interaction, first I’ll create an instance of the “SoftwareUser” class, and then the corresponding visitor object will be used for obtaining the values of all the properties exposed by the visited class.

The code snippet that performs all the tasks that I mentioned is listed below. Check it out:

try{
    // instantiate ‘SoftwareUser’ object
    $softwareUser=new SoftwareUser();
    // set properties for SoftwareUser object
    $softwareUser->setUserID(1);
    $softwareUser->setFirstName(‘John’);
    $softwareUser->setLastName(‘Smith’);
    $softwareUser->setPostalAddress(‘1245 Binary Avenue NY’);
    //$softwareUser->setEmail(‘john@domain.com’);
    $softwareUser->setPreferredSoftware(‘PHP’);
    // instantiate ‘SoftwareUserVisitor’ object
    $softwareUserVisitor=new SoftwareUserVisitor();
    // accept visitor
    $softwareUser->acceptVisitor($softwareUserVisitor);
    // visit ‘SoftwareUser’ object
    $softwareUserVisitor->visitSoftwareUser($softwareUser);
    $userData=$softwareUserVisitor->getSoftwareUserInfo();
    // display info about ‘SoftwareUser’ object via the visitor
    foreach($userData as $key=>$data){
        echo ‘Value for ‘.$key.’ is the following: ‘.$data.'<br />';
    }
}
catch(Exception $e){
    echo $e->getMessage();
    exit();
}

That was really easy, wasn’t it? As you can see, after assigning some trivial values to the properties exposed by the respective “SoftwareUser” object, the visitor in question is responsible for visiting it and displaying all the available information about this object.

With reference to the previous example, the last little thing to note is the usage of a “foreach” loop to output the complete set of values assigned to the properties of the “SoftwareUser” object. In order to complete the example, the result of this process is shown below:

Value for userid is the following: 1
Value for firstname is the following: John
Value for lastname is the following: Smith
Value for postaladdress is the following: 1245 Binary Avenue NY
Value for software is the following: PHP

After seeing the result of the above script, don’t say that implementing the visitor pattern in PHP 5 is hard work!

To wrap up

The second chapter of this journey is over. In this article I extended the application of the visitor pattern with PHP by walking you through another handy example, which demonstrated the correct implementation of this pattern.

However, this trip hasn’t finished yet. In the last part of the series, you’ll learn how to use a visitor object to establish a programmatic link between different MySQL result sets and a pager class. You won’t want to miss it!

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort