Archive for the 'Memento' Category

PHP Memento Design Pattern Part II: Store & Retrieve

mementoWith a Little Help from Our Friends

As you saw in Part I of the Memento Design Pattern post, the design itself is fairly simple; at least judging from the class diagram. Also, in the first example, you saw how a state could be preserved in a Caretaker array and recalled upon request. However, I wanted to use the Memento with a more practical implementation of remembering a previous state to which users could return. For instance, the capacity to remember a choice on a Web page after looking at a series of choices would be an ideal use of the Memento pattern. The idea is to build an encapsulated set of objects that encompasses the UI, and the previous post shows how that can be accomplished. The latest problem encountered using the Memento pattern with PHP is that PHP doesn’t have the necessary UI event handlers, and the UI event handlers in JavaScript, while able to pass data, must do so through a PHP file; not an object.

The result is that each time JavaScript passes a bit of data, it also re-instantiates a class in a file. When that happens, all of the stored states are reset to null. So while the Memento is great at storing data in an array (or scalar for that matter), getting that state back with another call via JavaScript (even if it’s encapsulated in a PHP object) nulls all of the stored states.

So, while JavaScript is OK for handling UI events and passing states to PHP, every state passed resets any saved states because the participants have to be re-instantiated. After trying out different methods, I eventually reached the conclusion that I was going to have to stash the Memento’s current state in a JSON (JavaScript Object Notation) file. PHP includes JSON methods, and while this does not exactly solve the problem of passing data without resetting the state, it can preserve the state stored in a Memento object. Take a look at the example and download the files to see all of the code employed:
PlayDownload

JSON and PHP

For those of you unfamiliar with JSON and PHP, you can find it here in the PHP Manual. As noted, to work with PHP and a Memento design pattern the way I wanted to implement it required that I have some way to provide a persistent record of a “saved state.” In a nutshell, JSON is a faster-loading version of XML with hooks into PHP where data can be exchanged. That is an oversimplification to be sure, but as far as I was concerned if a state could be saved and retrieved quickly when wanted, my requirements would be met. I did not want to involve MySQL, XML or simple text files (even though JSON files [ext .json] are text files). JSON was the fastest in saving and retrieving, and PHP has methods for parsing JSON data.

The Caretaker

If you have not done so already, read Part I of the Memento Design Pattern. That will bring you up to speed on the structure and participants of the Memento design pattern.

The Caretaker participant in the Memento pattern is the warehouse for the saved Memento objects passed through the Originator. Essentially, the Memento is passed to the Caretaker where it is stored until called for retrieval. However, a PHP object cannot be stored as a straight JSON file, and so once the Memento object is passed to the Caretaker (in this example), I passed the Memento value to a JSON file. The second Caretaker method returns the stored JSON value directly to the client rather than re-loading a Memento object and returning it. You can see how this all works in the Caretaker class code:

< ?php
class Caretaker
{
    private $storage;
    private $caretakerStore;
    private $caretakerStorage;
 
    public function addMemento (Memento $m)
    {
	$jsonData["hold"][0] = $m->getState();
	$this->caretakerStore="store.json";
	file_put_contents($this->caretakerStore,json_encode($jsonData,JSON_UNESCAPED_UNICODE));
    }
 
    public function getMemento()
    {
	$this->caretakerStorage = file_get_contents("store.json");
	$jsonData = json_decode($this->caretakerStorage,true);
	$this->storage= $jsonData["hold"][0];
	return $this->storage;
    }
}
?>

The two methods in the Caretaker are pretty straightforward getter/setter ones. The addMemento($m) method expects to receive a Memento object. (The type hint enforces it to.) However, instead of storing the entire Memento as was done in the example in Part I, the Caretaker uses the Memento’s getState() method to access the saved state. Then the state is stored in an associative array element named “hold.” ($jsonData[“hold”][0]). Written to a .json file the saved state might look like the following:

{"hold":["7"]}

The value “7” is the saved string that is used to recall the correct file (dp7.jpg) in the patterns folder. While this might appear to be breaking encapsulation, the value is returned in a Caretaker private property, $this->storage.

To get a better sense of the Caretaker in the context of this particular implementation take a look at Figure 2:

Figure 2: File diagram of Memento used for recalling Web image

Figure 2: File diagram of Memento used for recalling Web image

The PhpCatcher class is an attempt to encapsulate the HTML UI into an object and have methods available to set and retrieve Memento object values using the Caretaker as a warehouse. To set the Memento and send it to the Caretaker, the exact same object communications are used as in Part I. However, the Caretake extracts the value from the Memento and stores it in the .json file instead of in a PHP array that stays extant through UI interactions. So, to recall a Memento value, the PhpCatcher goes directly to the Caretaker’s getMemento() method. (Perhaps a more accurate name for the getter would be getMementoValue().) In any event, at the time of this posting, I was unable to find a way to store the Memento in a JSON object and retrieve it; so the PHPCatcher communicates directly with the Caretaker as a client.

You need to use PHP 5.4+ and you need to set your .json file permissions

  • The PHP built-in JSON methods and constants used require PHP 5.4. If you find it impossible to install 5.4, instead of using JSON, you can use a text file, an XML file or even a MySQL file for storing the Memento value.
  • File permissions are grouped into three categories:

    1. Owner
    2. Group
    3. Everyone

    Further, each permission has three levels:

    1. Read
    2. Write
    3. Execute

    You need to set your .json file so that everyone can read, write and execute the .json file. I set mine for ‘777’ so that all groups and the owner had total access. On your computer or LAN, there’s not a lot to worry about; however, if you are nervous about opening up your .json file to the world on your hosting service, you need to read up on permissions security to see if doing so will cause unwanted problems.

If you’re using a Raspberry Pi, you can find out how to change your permissions for this implementation here.

Continue reading ‘PHP Memento Design Pattern Part II: Store & Retrieve’

Share

PHP OOP: Encapsulating & Communicating with JavaScript and HTML5

EncapDocCan We Talk?

The initial discussion of the Memento design pattern illustrated how a state could be saved in a different object than the one in which the state originated. A Caretaker object holds the saved state and when requested, it returns the state to the Originator, all without breaking encapsulation. A practical example of employing the Memento that comes to mind is where the user is looking through a list. As she goes through the list, she sees different items (flowers in this case) that she is considering. However, because it’s a long list, she cannot remember which one she likes; so she tags those she is considering. After going through the whole list (all of the different flowers), she can easily recall those that she had tagged–recall them from a Memento. Play the little app and download the source code before going further:
PlayDownload

Communicating with HTML and JavaScript

Working HTML and JavaScript into PHP is no great shakes, and most PHP developers probably have done so at one time or another. However, most of the time I find myself creating horrible mixes of code for a one-off use with nothing encapsulated. The goal here is to see how everything in the application can be encapsulated and at the same time communicate. The purpose here is to find a single state variable that is used by HTML, JavaScript and PHP. Further, that state must be available for placing into a Memento object and stored for later use. (This post simply examines one way to encapsulate everything and have them communicate; however, material from this post will be used in developing a Memento example in a future post.) Also, I wanted to import all of the JavaScript and CSS separately. Figure 1 shows the general plan. (The ‘gardner’ folder contains the flower JPEG images.)

Figure 1: Encapsulating JavaScript, CSS and HTML into EncapDoc PHP class

Figure 1: Encapsulating JavaScript, CSS and HTML into EncapDoc PHP class

The CSS is just the stylesheet and it contained no functionality that you often find when it is used in conjunction with jQuery. I needed the JavaScript for clicking through the images. Had I swapped images using PHP I’d probably have to reload an HTML page with every swap and that seem prohibitively expensive. So I wrote the most simple JavaScript swap program I could think of with two functions for swapping and an added JavaScript function to get the initial starting picture (an integer value) passed from PHP. The following JavaScript listings shows how simple the script is:
Continue reading ‘PHP OOP: Encapsulating & Communicating with JavaScript and HTML5’

Share

PHP Memento Design Pattern Part I: Wide & Narrow Interfaces

mementoWhere’s the Interface?!

In going through Design Patterns: Elements of Reusable Object Oriented Software I found only three design patterns with no abstract class or interface parents: The Singleton, The Facade, and The Memento. I quit using the Singleton after several articles and even Erich Gamma said it caused more problems than it solved, and I have not had an occasion to use the Facade in a practical application (yet). However, I used the Memento pattern in the development of a script that controlled a streaming video. When the user decided that he/she wanted to remember a certain part of the video, the Memento would save the position of the video and would go back to that position if requested. The purpose of the Memento is to capture an internal state and store that state in an external object. It is the ultimate “un-do” pattern. You can save any given state, store it and then go back to it using the Memento design pattern.

Ironically, the major concepts to understand in Memento development are those of wide and narrow interfaces. Further, the Gang of Four note that this may be tricky with languages that do not support two levels of static protection. (As far as I know, PHP does not have that support, but I’ve developed a workaround that does the trick.) So, without further ado, let’s take a look at the Memento. Run the program and download the files if you’d like:
PlayDownload

Saving State

The task of saving state is as simple as saving certain property values in a variable or array. For example, if you’re keeping score in a game, generally you just increment or decrement a variable. At some point you may wish to save a score and later on use it again. Let’s say that if a player reaches 100, you want to record that so that it can be used later in determining his/her character status. The Memento will do that for you and store a given state in a separate object, and the trick is to capture and retrieve that state without breaking encapsulation.

Without violating encapsulation, capture and externalize and object’s internal state so that the object can be restored to this state later.(GoF p. 283)

Figure 1 is the class diagram for that process:

Figure 1: Memento Design Pattern

Figure 1: Memento Design Pattern

It looks pretty simple, but it’s easy to get wrong, and if you look around on the internet, you’ll find plenty of bad examples. So let’s start with wide and narrow interfaces. (I thought you said it didn’t have interfaces!)

Wide and Narrow Interfaces

In most class diagrams, we will see a Client class—if not in the original class diagram, I generally put one in to use as a starting point. However, with the Memento, the Caretaker makes a request for a Memento from the Originator; so it acts like a Client. The Caretaker is supposed to act pretty much like a warehouse—it stores Memento objects, but it doesn’t alter their states. Then, upon request, it returns them.
Continue reading ‘PHP Memento Design Pattern Part I: Wide & Narrow Interfaces’

Share