pureMVC simple StateMachine utility

*Update see this post for the latest version*

Here is an implementation of a simple State Machine for pureMVC that I whipped up for a project. This is really useful for anyone creating applications, honest, its saved my life a few times :) It suddenly occurred to me that because its so simple I’ve been taking its power for granted, and I should share it for the greater geek good. I’ve been using it in combination with trilec’s command chaining utility as a way of controling my command structures.

Have put the code in the svn on my google code page and will prepare a download when I’ve documented it.

Initiate the StateMachine

// instanitate 
var stateMachine:StateMachine = new StateMachine();
// register with the facade before registering any commands
facade.registerMediator(stateMachine);
// create a state 
var state:State = new State(ApplicationStates.STATE_ONE)
// register the commands to be triggered when 
// entering and exiting that state 
stateMachine.registerStateChangeCommands(EnterStateOne,
                                         ExitStateOne,
				         state);
// repeat for each state (this can be done any time)
state = new State(ApplicationStates.STATE_TWO)
stateMachine.registerStateChangeCommands(EnterStateTwo,
                                         ExitStateTwo,
				         state);

Changing State
This is very simple, just send a notification from anywhere within the pureMVC framework with a new state as its body:

// create a state 
var state:State = new State(ApplicationStates.STATE_TWO)
sendNotification(StateNoteNames.CHANGE_APPLICATION_STATE,
                 state))

[kml_flashembed movie=”http://www.revisual.co.uk/uploads/2008/oct/statemachine/state_machine_demo.swf” height=”300″ width=”470″ /]

The Singleton

(originally posted on FlashBrighton)

The Singleton is the simplest and most widely used Design Pattern, and so it is often used as the starting point. It is how ever also the most widely misused, and one of the most controversial.

intent: to restrict a class to only one instance, and provide a global point of access to it.

motivation: Sometimes we want just a single instance of a class to exist in a system

structure:
class diagram for singleton pattern

example 1 (AS3):

public class Singleton{

    // holds the unique instance of the 
    // Singleton in a class vars
    private static var _uniqueInstance:Singleton;

    // the constructor
    public function Singleton(validator:Number):void{
        // code
    }
		           
    // provide access to the unique instance 
    // through a class method
    public static function getInstance():Singleton{   
        
        // lazy instantiation of unique instance:
        // if it don't exist, create it
        if (_uniqueInstance == null)
                _uniqueInstance=new Singleton( );

        //send it back
        return _uniqueInstance;
    }
}

and this is how the singleton instance is accessed:

var mySingleton:Singleton = Singleton.getInstance()

Pretty simple really, but there are some things to note

  • the lazy instantiation means that the instance is not created unless it is needed, saving memory wastage. Now this presents no problems in AS (as it is single-threaded), but in a multi-threaded environment, the instantiation must be synchronised to prevent multiple instances being created by different threads.
  • in AS, a constructor can not be private, so the above example is open to misuse, as the constructor can still be accessed by any client. It is not properly a Singleton yet, so some form of validation must be required to instantiate it.

example 2 (AS3):

public class Singleton{

    // the singleton validation key
    private static const SINGLETON_KEY:Number = Math.random();

    private static var _uniqueInstance:Singleton;

    // the constructor now requires an argument, 
    // the SINGLETON_KEY which is private, different
    // for every application run, and can not be 
    // accessed from outside the class
    public function Singleton(key:Number):void{
        if (key != SINGLETON_KEY)
                throw new Error("private constructor");
        // code
    }
		           
    public static function getInstance():Singleton{   
        
        // this time we pass in the key 
        if (_uniqueInstance == null)
                _uniqueInstance=new Singleton(SINGLETON_KEY);

        return _uniqueInstance;
    }
}

Ok, so now only the static method getInstance() can create a new instance of the Singleton Class, trying to access the constructor with out the required key will throw an error.

We are good to go.

Or are we?

Singleton: the anti-pattern

  1. just because one system needs only one instance of a certain class, doesn’t mean that another one does also. If this is the case, then the class should not be a Singleton, and to do so, is really just using a Singleton as a glorified global variable (GlobalVariablesAreBad). There will be a better way for a client to obtain the instance required.
  2. because a Singleton manages its instance through a static method:
    1. sub-classing is possible, but fraught with complications
    2. it can not implement an interface
    3. all references must be hard-coded with the name of the class, promoting (as b does) tight coupling between classes
  3. therefore, Singletons can not be polymorphic
  4. a Singleton manages its own instantiation, but it also manages its own business logic. This violates the Single Responsibility Principle.
  5. a Singleton’s state persists as long as the application is running – this is very bad for unit testing, as it out-lives any unit that is being tested (apparently).

conclusion

  • Before you make a class a Singleton, ask yourself this: will it be implemented in exactly the same way for every client that will ever use it and always be required to have a single instance? If the answer is yes, then A Singleton is a valid choice.
  • If you encapsulate the management of the Singleton instance in another class, then the Singleton can implement an interface, can be sub-classed, if needed – be used as a non-Singleton, and be left to get on with its own business logic in polymorphic heaven.