Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News


2008 West
DIAMOND SPONSOR:
Data Direct
SOA, WOA and Cloud Computing: The New Frontier for Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
GOLD SPONSORS:
Appsense
User Environment Management – The Third Layer of the Desktop
Cordys
Cloud Computing for Business Agility
EMC
CMIS: A Multi-Vendor Proposal for a Service-Based Content Management Interoperability Standard
Freedom OSS
Practical SOA” Max Yankelevich
Intel
Architecting an Enterprise Service Router (ESR) – A Cost-Effective Way to Scale SOA Across the Enterprise
Sensedia
Return on Assests: Bringing Visibility to your SOA Strategy
Symantec
Managing Hybrid Endpoint Environments
VMWare
Game-Changing Technology for Enterprise Clouds and Applications
Click For 2008 West
Event Webcasts

2008 West
PLATINUM SPONSORS:
Appcelerator
Get ‘Rich’ Quick: Rapid Prototyping for RIA with ZERO Server Code
Keynote Systems
Designing for and Managing Performance in the New Frontier of Rich Internet Applications
GOLD SPONSORS:
ICEsoft
How Can AJAX Improve Homeland Security?
Isomorphic
Beyond Widgets: What a RIA Platform Should Offer
Oracle
REAs: Rich Enterprise Applications
Click For 2008 Event Webcasts
SYS-CON.TV
Top Links You Must Click On


Un Momento, Por Favor
A brief glimpse into software design patterns and their usefulness

When developing applications, it's very common to find situations where you'd like to remember the state of an application, either in whole or in part, and later return your application to a previous state.

Let's take a look at a real-world example...

Your footsteps echo down the unmarked path. Gravel shuffles everywhere as you slow and strafe around the corner of a generic concrete bunker. You reach for the double- barreled shotgun but it's too late. A loud bang rips through the air but it's the soft thud as you hit the ground that confirms your worst fear, you're dead...again. A quick click of the mouse and poof...like magic you're all the way back to your last reached checkpoint.

If you're like me, you're all too familiar with this scenario. When you reach the checkpoint for the first time, the application quickly stores essential information about your character's current state. Your state might consist of things like health percentage, the existence and condition of body armor, a list of carried items and your checkpoint location. This information is bundled into a "game state" object and stored quietly behind the scenes. Later on, when you fail miserably to reach the next checkpoint, the game state object is loaded and the application is restored to a previously defined state.

In addition to the application state as a whole, you may find the need to record the state of smaller parts. We can also find examples of this in our favorite first-perso n shooter. For example, the state of a room you enter might be stored in a "room state" object when you leave the room. This object may store a list of items and their locations, existence of any damage, etc. This way, the guard you fragged will still be lying on the floor and the health pack you picked up will still be missing when you re-enter the room later. A "caretaker" object would be responsible for holding each of a level's room state objects in a randomly accessible list so that the application can retrieve the state of any room it needs to. By utilizing a room state object, when you leave a room the game is able to unload the overhead the room might consume with its textures and objects yet maintain the ability to easily recreate the room by loading it in its default state then modifying it with information found in a room state object.

While these examples are game-specific, the same concept can be seen in almost any application. In fact, the undo feature is the quintessential example of restoring an application to a previous state. Multiple undos are implemented by storing command objects in a stack. The last command added to the stack is the first to be retrieved by CTRL+Z, creating a last-in, first-out scenario.

From a mile-high view, the undo feature, room states, and checkpoint spawning are all basically the same thing. Therefore, it would be reasonable for us to assume that each of these scenarios can be implemented in a similar way if we were to describe their solutions from a similar distance.

Software Design Patterns
Software design patterns are practical solutions to the common software design problems we face when developing applications. While software design patterns were a concept first adapted from architectural design patterns in 1987 by Kent Beck and Ward Cunningham, they didn't really become popular until about seven years later. In 1994, the book Design Patterns: Elements of Reusable Object-Oriented Code by the "Gang of Four" (Gamma et al) was released and object-oriented programming practices were changed as design patterns became very popular.

Critics of design patterns argue that the abstract solution a design pattern provides often increases the amount of code needed to implement the solution. They also state that, by adding code not specific to the project, you go against the principles of "best practice" programming. Many advocates of design patterns, like me, recognize these cons but believe the pros outweigh them by far and do, in fact, promote "best practice" solutions in a way of their own. Yes, with design patterns you're implementing abstract solutions, but so what? After all, if it's considered "best practice" to design abstract classes, why can't solutions be abstract? To me, patterns end up providing a more scalable solution than I might have implemented had I chosen to write something specific to the project. Another major advantage is the ability to have a common language with other developers, especially ones I've never met.

Without design patterns, developers working in teams need to do more planning and collaboration to implement the same solution, since each developer's prior experience may have led them to different solutions to the same problem.

"Hey Mike, I think we need to take a snapshot of the game at each checkpoint so that we can restore the game to a point in time when the player dies."

"Yeah, you're right, John. I remember on the Acme project we wrote some classes that stored small pieces of information we later used to restore the application."

"I dunno, I didn't work on the Acme project so I'm not at all familiar with how they handled it. But what you describe sounds more like what we did on the Foo video player."

"No, not really. With the Foo player we had that hack Joe work on the project and we ended up changing it a bit afterwards. I was thinking more like..."

Anyway, you get the idea. Wouldn't something like the following be easier?

"Hey Mike, I think we should implement the Memento design pattern for the room states."

"Yeah, no doubt. I'll go ahead and write the memento class. Do you want to write the caretaker class?"

By implementing a design pattern, the developers can reuse the amount of time spent on this feature.

The Memento Pattern
As you've likely guessed from the blatant hints so far, I was leading up to discussing the Memento pattern. The Memento pattern is easy to understand, since it's frequently used and easily identifiable.

The Memento pattern is typically made up of three objects: the originator, the memento, and the caretaker.

  • Originator - The object of focus, the state of which we want to save and restore. This object would have two public methods:
  • getState():object - Returns a memento object to the caller, which will be the caretaker object
  • restoreState(object):Boolean - Called by the caretaker passing in the memento object so that the originator can restore its state
  • Memento - A container object that will encapsulate the essential information required to restore the originator
  • Caretaker - An object that will store the memento object for the originator. It will provide the memento object to the originator when the originator needs to be restored.
In a nutshell, the Memento object is created by the originator object, and then stored in a caretaker object. The caretaker supplies the originator with a memento when the originator needs to restore its state.

Let's examine a simple version the Memento design pattern by creating a Flash SWF player you might typically see on the homepage of a site. The main SWF is a parent SWF that loads children SWFs, each of which play as animations and have some level of interactivity. In this example, the main SWF would be the caretaker, the currently loaded child SWF would be the originator and the memento would be an object created by the child and stored in the parent. The reason we need to store the memento in the caretaker and not the originator is that we'll unload the originator when we load the next SWF in the playlist. By using a caretaker, the memento can persist after the originator is gone.

For a simple illustration of the concept, I show the implementation below using more of a procedural method of programming. An object-oriented approach would be better to enforce encapsulation and prevent non-originator access to the memento content. On my Web site at www.jamesor.com/downloads/wddj/mementos.zip you can find the full source code to both procedural and object-oriented implementations.

In our parent movie, we create a list to hold our memento objects:

// list to hold memento objects
var aryMementos:Array = new Array(5);
var nLastIndex:Number = 0;
// when you change the child SWF,
// the first thing you do is save
// a memento of the currently loaded
// slide then changed to the new
// slide and if we have a memento
// for the new slide, then restore it
function changeSlide (i:Number) {
    // store memento of current slide
    aryMementos[nLastIndex] = child_mc.getCurrState();
    // load in the new child movie
    ... code to load child SWF i ...
    // pass child back it's memento
    if (aryMementos[i] != undefined) {
       child_mc.restoreState(aryMementos[i]);
    }
    nLastSlideIndex = i;
}

On frame one in our each of our child movies, we include getter and setter like functions for creating and restoring mementos:

function getCurrState ():Object {
    // store all of the relevant data
    // into a memento object
    var memento:Object = new Object();
    memento.frame = _currentframe;
    memento.name = name_txt.text;
    memento.foo = "bar";
    ... whatever else you need ...
    return memento;
}
function restoreState (memento:Object):Void {
    // restore any saved data
    name_txt.text = memento.name;
    ... plus the remaining data ...
    gotoAndPlay(memento.frame);
}

Since we defined our memento object inside the child SWF, we can have unique memento definitions for each child we load. The caretaker doesn't care what's inside the memento objects; it just stores them in an array and returns them as objects when needed.

Occasional Connectivity
If you connect to the Internet with a laptop, you're probably familiar with being online only some of the time. You may lose your wireless signal going through a tunnel on the train or just have no access at all until you're back in the office plugged into a LAN line.

One way to improve a user's experience and meet their ever-increasing expectations of RIAs might be to implement the Memento pattern on a complex form. This way, if a connection is lost before the user gets to submit a complex form, you could create a memento object that contains all of the form field data on the screen. This memento object can be stored on the user's hard drive and later retrieved so it can be submitted the next time an Internet connection is available.

Using the SharedObject, we can easily store and retrieve a memento object.

// Get the flash cookie named
// "memento" or create one if
// it does not already exist
// and get that.
var my_so = SharedObject.getLocal("memento");

if (weRealizeThereIsNoConnection) {
    // store our memento object inside
    // the data object of our
    // SharedObject
    my_so.data.memento = oOriginator.getCurrState();
    my_so.flush();
} else {
    if (my_so.data.memento!=undefined){
      // restore our originator
      oOriginator.restoreState(my_so.data.memento);
      // now that the data is restored
      // and a connection is available,
      // try sending the data again
      ...try submitting data again...
    }
}

About James O'Reilly
James O'Reilly lives on Long Island, New York where he has been developing Web-based applications for roughly 11 years. Currently, James focuses on Flash, ASP.NET, and SQL Server to create RIAs for industry-leading clients.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Enterprise Open Source Magazine Latest Stories . . .
Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP). The...
With Cloud Expo 2012 New York (10th Cloud Expo) just four months away, what better time to start introducing you in greater detail to the distinguished individuals in our incredible Speaker Faculty for the technical and strategy sessions at the conference... We have technical and st...
AMD said late Tuesday that its chief sales officer Emilio Ghilardi had left the company and that CEO and president Rory Read is going to do his job while a replacement is sought. AMD didn’t say why Ghilardi left but it’s assumed Read wants his own people. Read is relatively new to th...
During the lifespan of M3 (Monitis Monitor Manager) there has always been something lacking – timers. M3 execution procedure was outlined in this previous article. The execution mentioned in the latter was a one-time-execution, whereas server monitoring requires periodic invocati...
Red Hat is putting its bought-in Gluster scale-out NAS storage technology, acquired in October, on the Amazon cloud. It’s styled Red Hat Virtual Storage Appliance for Amazon Web Services and other clouds are supposed to follow in short order.
A new episode of the screencast series is now available at the OpenNebula YouTube Channel. This screencast demonstrates the new easily-customizable self-service portal for cloud consumers. Its aim is to offer a simplified access to shared infrastructure for non-IT end users. The scree...
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON Featured Whitepapers
ADS BY GOOGLE