Design Patterns in Flash

Now Actionscript is OO, I thought it would be useful to try out implementing a design pattern in Flash. The pattern I chose is the Memento pattern, which is mainly used to implement “undo” functionality in applications. The reason I chose Memento is because its a pattern that uses interfaces and I wanted to explore this in AS 2.0. An interface is an object that defines methods but has no implementation.

The Memento pattern consists of three objects, Originator, Memento and Caretaker. The Originator is the object of which all or some properties need to ‘saved’. These properties are saved in a Memento object. Finally the caretaker object is in charge of any saving or ‘undoing’.

Any object that wants its state to be stored for possible retreival later (Originator) must have two methods defined. These are setMemento() and createMemento(). An interface for this would look like this:

1interface com.nodetraveller.patterns.Memento.iOriginator {
2	function setMemento(m:iMemento):Void;
3	function createMemento():iMemento;
4}

The setMemento has one parameter (Memento) and its job is to extract the properties from it and revert the Originators own state using those properties. So this is used after its state has been saved. To save a state, the createMemento method is used. This returns a memento object which has all the properties that the originator wants saved. To implement the originator interface we would write something like this:

 1import com.nodetraveller.patterns.Memento.*;
 2
 3class com.nodetraveller.patterns.Memento.Originator implements com.nodetraveller.patterns.Memento.iOriginator{
 4	private var _text:String = "";
 5	private var _isChecked:Boolean = false;
 6
 7	public function setMemento(m:Memento):Void {
 8		this._text = m.getText();
 9		this._isChecked = m.getChecked();
10	}
11
12	public function createMemento():Memento {
13		return new Memento(_text,_isChecked);
14	}
15}

This class has two properties (a string and a boolean type) that is saved using a memento object. This memento then only needs the same properties that the originator wants saved and relevant getters and setters.

 1import com.nodetraveller.patterns.Memento.*;
 2
 3class com.nodetraveller.patterns.Memento.Memento {
 4	private var _text:String;
 5	private var _isChecked:Boolean;
 6
 7	function Memento(text:String,checked:Boolean) {
 8		this._text = text
 9		this._isChecked =checked;
10	}
11
12	public function getText():String {
13		return this._text
14	}
15
16	public function getChecked():Boolean {
17		return _isChecked;
18	};
19}

Now that we have the originator and the memento, all thats left is the caretaker.

 1import com.nodetraveller.patterns.Memento.*;
 2
 3class com.nodetraveller.patterns.Memento.Caretaker {
 4	private var _orig:Originator
 5	private var _memento:Memento;
 6
 7	function Caretaker() {
 8	_orig = new Originator();
 9	};
10
11	function saveState(){
12	this._memento = _orig.createMemento();
13	}
14
15	function revertState(){
16	this._orig.setMemento(_memento);
17	}
18}

The saveState method calls the createMemento method on the Originator which returns a memento which the caretaker keeps. When the originator needs to be reverted, the caretaker set the originators memento to the one it saved.

Ideally, the getter and setters for the Memento shouldn’t be public as only the Originator should have access. In Java, this would be implemented using inner classes.

I’ve created a fla using these classes here. Its a simple demo showing a textArea and a checkbox which you can save and revert

**Note: **In the Caretaker class of the zip, I’ve put the eventhandlers for the GUI. In a real app these would probably be in another object. Also you may have to add the path where you saved the files to Flash’s classpath. This can be done in Edit->Preferences.