Introducing the Memento Pattern

PHP developers frequently need to maintain the state of an object across several web pages. There are a number of ways to do this. In this article, the first of two parts, you will learn how to handle this task with the memento pattern.

Introduction

As the seasoned PHP developer that you certainly are, you’ll probably know that one of the easiest ways to track and maintain the state of several variables across different HTTP requests is by using the neat capabilities of sessions. These have been included for a long time with the different PHP distributions.

Moving toward PHP object-oriented programming, it’s easy to maintain the state of a certain object across several web pages because a single instance of a class can be also stored onto a typical session variable.

While the above mentioned process is one of the most common tasks that a PHP programmer has to tackle when developing a web application, it is fair to say that an object can also be tracked by using a design pattern. Logically, at this moment you’re wondering: what pattern is capable of doing that? Well, I’m glad you asked, since the answer to your question is the memento pattern.

To put it simply, when this pattern is used in the context of a given application, two classes are involved: the first one is called the originator, while the second one is denoted the caretaker. Despite the funny names assigned to these classes, which may lead one to think that this pattern is rather useless, the truth is that it can be pretty handy for holding the state of a particular class.

In accordance with the schema of classes that I described a few lines above, the caretaker would be responsible for maintaining the state of the originator by using one or more methods. However, the implementation of this pattern is particularly interesting, since the caretaker object will keep track of the state of the originator by using only the interface of the originator.

Does this definition sound confusing? Don’t you worry about it for the moment, because in this two-part series, I’m going to demonstrate with numerous code samples how to apply the memento pattern so that it can be used within your own PHP applications with only minor problems.

Having defined the goal of this new series, come with me and learn how to implement this useful pattern with PHP 5. Do we have a deal? Okay, let’s get started.

{mospagebreak title=Creating the first piece of the memento pattern}

As I clearly explained in the introduction of this article, when it comes to applying the memento design pattern it’s necessary to define two classes, called the originator and the caretaker respectively. In this tutorial, I’m going to demonstrate how to use the pattern by creating the originator first, and then the caretaker.

In this case, the functionality housed within the originator will involve traversing an array structure, which will be directly inputted into the class via its constructor.

Having explained briefly how the originator class will work, take a look at its corresponding definition. It is as follows:

// define ‘ArrayProcessor’ class (in this case, this is the Originator class)
class ArrayProcessor{
   private $inputArray;
   private $arrayIndex;
   // set input parameters
   public function __construct($inputArray,$arrayIndex=0){
     if(!is_array($inputArray)){
       throw new Exception(‘Invalid input array!’);
     }
     if($arrayIndex<0||$arrayIndex>(count($inputArray)-1)){
       throw new Exception(‘Invalid index value for input array!’);
     }
     $this->setInputArray($inputArray);
     $this->setArrayIndex($arrayIndex);
   }
   // set input array
   public function setInputArray($inputArray){
     $this->inputArray=$inputArray;
   }
   // fetch input array
   public function getInputArray(){
     return $this->inputArray;
   }
   // set value for ‘arrayIndex’ property
   public function setArrayIndex($arrayIndex){
     $this->arrayIndex=$arrayIndex;
   }
   // get value of ‘arrayIndex’ property
   public function getArrayIndex(){
     return $this->arrayIndex;
   }
   // fetch array element according to array index
   public function getArrayElement(){
     if(!$elem=$this->inputArray[$this->arrayIndex]){
       throw new Exception(‘Error fetching element of input array!’);
     }
     return $elem;
   }
}

As you’ll realize, the signature of the above “ArrayProcessor” class is pretty straightforward. In this case, the class has been defined as the originator. It presents some simple methods for traversing a given array via an index parameter, which is also inputted through the respective constructor.

Aside from describing the core tasks performed by the aforementioned originator class, there’s not much to be said about it (at least for the moment). However, don’t feel disappointed, since this is only the first building block of the memento pattern.

As you learned before, there’s another class involved in this schema: the caretaker class. In the next section I’m going to create this new class and show you how it can hold a specific state of the previous originator. Please click on the link below and keep reading. 

{mospagebreak title=Building the second piece of the memento pattern}

In consonance with the concepts that I expressed in the prior section, the schema imposed by the memento pattern must be completed by creating an additional class, called the caretaker. As its name implies, this class will take care of holding a specific state of the previously defined originator, completing the logic implemented by the pattern in question.

However, before I teach you how to put the two pertinent classes to work together, first let me show you the signature that corresponds to the caretaker. In this you will understand later how this new class interacts with the respective originator.

Here is the definition for a brand new class, called “ArrayElementSelector.” It plays the role of the caretaker. Have a look at its signature, please:

// define ArrayElementSelector’ class (in this case, this is the Caretaker class)
class ArrayElementSelector{
   // the constructor accepts the originator as the unique parameter
   public function __construct(ArrayProcessor $arrayProcessor){
     $this->setInputArray($arrayProcessor);
     $this->setArrayIndex($arrayProcessor);
   }
   // set input array by using originator object (ArrayProcessor)
  public function setInputArray(ArrayProcessor $arrayProcessor){
    $this->inputArray=$arrayProcessor->getInputArray();
  }
  // get input array by using originator object (ArrayProcessor)
  public function getInputArray(ArrayProcessor $arrayProcessor){
    $arrayProcessor->setInputArray($this->inputArray);
  }
  // set array index by using originator object (ArrayProcessor)
  public function setArrayIndex(ArrayProcessor $arrayProcessor){
    $this->arrayIndex=$arrayProcessor->getArrayIndex();
  }
  // get array index by suing originator object (ArrayProcessor)
  public function getArrayIndex(ArrayProcessor $arrayProcessor){  
    $arrayProcessor->setArrayIndex($this->arrayIndex);
  }
}

As you can see, the class shown above implements a classic structure for a caretaker class. As you’ll recall from the concepts that I explained in the introduction of this article, the previous class is only capable of accessing the originator via its interface, and never directly. Pretty weird, right?

Of course, this condition is clearly reflected by each of the methods exposed by the respective caretaker. As you can see, these methods access and set the index of the given input array (and its elements too) only by using the originator object.

Besides, I’d like you to pay attention to the signature of the following method, which is extremely demonstrative:

// set array index by using originator object (ArrayProcessor)
public function setArrayIndex(ArrayProcessor $arrayProcessor){
 
$this->arrayIndex=$arrayProcessor->getArrayIndex();
}

Do you see how the value of the “arrayIndex” property is accessed by using an ArrayProcessor’s method? I bet you do! As you’ll see soon, this condition is crucial for holding the state of a specific property that belongs to the originator, which  leads straight to the definition of the memento pattern.

All right, now that you hopefully learned how the originator class does its business, as well as how the corresponding caretaker interacts with it, it’s time to jump forward and develop a hands-on example. This example will demonstrate in a friendly fashion how the previous “ArrayElementSelector” class is capable of maintaining the value of the “arrayIndex” property that corresponds to “ArrayProcessor.”

Do you want to see how this example will be created? Please visit the following section and keep reading.

{mospagebreak title=Implementing the memento pattern}

As I said at the end of the section that you just read, the best way to understand the logic that drives the memento pattern is by creating a hands-on example that shows in a step-by-step format how a caretaker object can hold the state of a property that belongs to an originator.

Based upon this premise, below I set up the example in question. It  demonstrates progressively how the previously created “ArrayElementSelector” class has the capacity to retain the value of the “arrayIndex” property that belongs to the “ArrayProcessor.” The corresponding code sample is as follows:

try{
    // example using Originator and Caretaker classes
    // instantiate new ‘ArrayProcessor’ object
    $arrayProcessor=new ArrayProcessor(array(‘This is element 1′,’This is element 2′,’This is element 3′,’This is element 4′,’This is element 5′));
    // instantiate new ‘ArrayElementSelector’ object
   $arrayElemSelector=new ArrayElementSelector($arrayProcessor);
   // display first element of input array
   echo ‘First element of input array is the following: ‘.$arrayProcessor->getArrayElement();           

   /* displays the following:
   First element of input array is the following: This is element 1
    */           

    $arrayProcessor->setArrayIndex(1);
    $arrayElemSelector->setArrayIndex($arrayProcessor);
    // caretaker object holds up the value of array index
    $arrayElemSelector->setArrayIndex($arrayProcessor);
    echo ‘Second element of input array is the following: ‘.$arrayProcessor->getArrayElement();

    /*
    displays the following:
    Second element of input array is the following: This is element 2
    */

    // move array index to nonexistent element of input array
    $arrayProcessor->setArrayIndex(10);
    echo $arrayProcessor->getArrayElement();

    /* 
    displays the following:
    Error fetching element of input array!
    */

    // move array index back to second element of input array by using caretaker object
    $arrayElemSelector->getArrayIndex($arrayProcessor);
    $arrayProcessor->getArrayIndex();
    echo ‘Second element of input array is the following: ‘.$arrayProcessor->getArrayElement();

   /*
   displays the following:
   Second element of input array is the following: This is element 2
   */

}
catch(Exception $e){
   echo $e->getMessage();
   exit();
}

As illustrated above, after instantiating the two objects required by the memento pattern, that is the originator (in this case, represented by the ArrayProcessor class), and the caretaker (as you know, the “ArrayElementSelector class), the first element of the inputted array is properly displayed.

However, the actual capacity of the pattern is demonstrated when the “ArrayElementSelector” object stores the value of the “arrayIndex” property, before moving this index forward and trying to display a non-existent array element:

// caretaker object holds up the value of array index
$arrayElemSelector->setArrayIndex($arrayProcessor);
// move array index to nonexistent element of input array
$arrayProcessor->setArrayIndex(10);
echo $arrayProcessor->getArrayElement();

Obviously, this condition fires up an exception and the script is halted. But, since the caretaker has previously maintained the state of the “arrayIndex” property, it’s possible to go back and redisplay the second element of the inputted array. As you can imagine, this situation is demonstrated by the following lines of code:

// move array index back to second element of input array by using caretaker object
$arrayElemSelector->getArrayIndex($arrayProcessor);
$arrayProcessor->getArrayIndex();
echo ‘Second element of input array is the following: ‘.$arrayProcessor->getArrayElement();

Now, after understanding how the originator and caretaker classes work together, I’m sure that you’ll agree with me that the memento pattern comes in handy for maintaining the state of a particular class. Isn’t this great?

Wrapping up

Over this first installment of the series, I explained the basics of how to apply the memento pattern in PHP 5. Aside from being introduced to the concepts of the originator and caretaker classes respectively, hopefully you learned how to store the state of a given class by using another one, which is indeed useful.

However, this journey is not finished. In the last article of the series, I’ll show you how to use the memento pattern to hold the state of a file reading class. I hope to see you there!

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

chat sex hikayeleri Ensest hikaye