Archive for the 'Object Oriented Design' Category

Multiton Pattern in ActionScript 3

Wednesday, September 26th, 2007

If you are familiar with the standard GoF Patterns than you more than likely are aware of the Singleton Pattern and the solutions which it provides.

For those of you who are not familiar with the Singleton Pattern it is a Creational Pattern which, when implemented as prescribed ensures only one instance of a class is ever instantiated. This is facilitated via a single global access point from which a singleton instance is to be created and or retrieved.

You may be wondering just what the Singleton Pattern has to do with the Multiton Pattern? And how does the Singleton pattern relate to the Multiton pattern? What are the differences and what are the similarities?

To answer your question the Multiton pattern is a Creational pattern which builds on the concept of the Singleton pattern by adding a mapping of key / value [object] pairs.

Unlike the Singleton Pattern, whereas there is only ever a single instance of an object created, the Multiton pattern ensures that only a single instance of an object is created per key. Therefore there are multiple instances which are managed via the Multiton object. The Multiton pattern provides centralized access of Multiton objects and advocates keyed storage of objects within a system.

Below is a simple example which demonstrates an implementation of the Multiton Pattern in ActionScript 3.0:

package
{
  import com.ericfeminella.utils.HashMap;
  import com.ericfeminella.utils.IMap;
   
  public final class Multiton
  {
      private static var instances:IMap = new HashMap();
       
      public function Multiton(access:Private)
      {
          if (access == null)
          {
              throw new Error( "Abstract Exception" );
          }
      }

      public static function getInstance(key:*):Multiton
      {
          var instance:Multiton=instances.getValue(key);

          if ( instance == null )
          {
              instance = new Multiton( new Private() );
              instances.put( key, instance );
          }
          return instance;
      }
       
       public function get id() : *
       {
           return instances.getKey( this );
       }
    }
}

class Private {}

Here is a breakdown of the above example.

First a new class is created as well as an additional inner class outside of the package which is used to ensure the constructor can only be called from within the class body, in this case the Multiton class.

package
{
  public final class Multiton
  {
      public function Multiton(access:Private)
      {
          // verify that access is not null
          // if it is, then an illegal request
          // to instantiate the constructor
          // is being attempted
          if (access == null)
          {
              throw new Error( "Abstract Exception" );
          }
      }
   }
}

/**
 * inner class restricting constructor access to private
 */

class Private {}

Next a private or protected static var of type HashMap (optionally, a generic Object or Dictionary can be substituted) is defined. The static HashMap instance contains the mappings of keys to objects in the Multiton class. Each key only ever contains a single Multiton object instance, and each Multiton instance can only be accessed by it’s associated key.

package
{
  import com.ericfeminella.utils.HashMap;
  import com.ericfeminella.utils.IMap;
   
  public final class Multiton
  {
      // contains key / Multiton instance mappings
      private static var instances:IMap = new HashMap();
       
      public function Multiton(access:Private)
      {
          if (access == null)
          {
              throw new Error( "Abstract Exception" );
          }
      }
   }
}

/**
 * inner class restricting constructor access to private
 */

class Private {}

Lastly, Multiton implementations require a public static method; getInstance(); which is very similar to the static getInstance() as it applies to the Singleton pattern, but with a slightly different signature. The getInstance(); method in a Multiton requires a single parameter which specifies the key from which a new instance is to be assigned and / or retrieved.

Certain Multiton implementations use an object as the key, however it is arguably more intuitive to use a primitive type such as a String to define keys. Regardless, I prefer not to enforce type restraints as the implementation will typically depend on the context in which it is being applied.

package
{
  import com.ericfeminella.utils.HashMap;
  import com.ericfeminella.utils.IMap;
   
  public final class Multiton
  {
      private static var instances:IMap = new HashMap();
       
      public function Multiton(access:Private)
      {
          if (access == null)
          {
              throw new Error( "Abstract Exception" );
          }
      }

      // retrieve the appropriate Multiton instance
      // if the instance does not currently exist
      // one will be instantiated and mapped to
      // the specified key. All subsequent client
      // requests will return the correct instance
      public static function getInstance(key:*):Multiton
      {
          var instance:Multiton=instances.getValue(key);

          if ( instance == null )
          {
              instance = new Multiton( new Private() );
              instances.put( key, instance );
          }
          return instance;
      }
   }
}

class Private {}

To implement a Multiton instance all that is needed is to invoke the static getInstance(); on the Multiton class object just as one would invoke getInstance() on a singleton class object. However in the Multiton it is assumed that there will be many instances, albeit controlled instances, therefore a key must be specified.

Below is a simple example which demonstrates how to retrieve a specific instance of a Multiton object:

var multiton1:Multiton = Multiton.getInstance( "a" );
trace( multiton1.id ); // a

var multiton2:Multiton = Multiton.getInstance( "a" );
trace( multiton2.id ); // a

var multiton3:Multiton = Multiton.getInstance( "o" );
trace( multiton3.id ); // o

There is not to much documentation on the Multiton Pattern outside of the Ruby community and a Java implementation available on wikipedia, however the Multiton Pattern proves very useful when multiple, controlled object instances are needed.

AIR Cairngorm (AIR extensions for Cairngorm)

Monday, July 16th, 2007

I have developed an open source ActionScript 3 project called “AIR Cairngorm” which is intended to provide a framework for working with the new Adobe AIR services while utilizing the Cairngorm-micro architecture.

When I say AIR Services, I am referring to the SQLite and FileSystem APIs, which are available in Adobe AIR.

AIR Cairngorm provides a framework which developers can employee to build typical Cairngorm applications that utilize these services.

The following is a brief description of the AIR Cairngorm API:

AIRServiceLocator: The AIRServiceLocator is a sub class of Cairngorm ServiceLocator, therefore it inherits the same API as ServiceLocator, and adds an additional API for working with local databases.
view source

SQLService: The SQLService is essentially a wrapper class for the SQLStatement and SQLConnection classes. The SQLService class allows developers to create an mxml implementation just as one would with typical HTTPServices, WebService and so forth in a Cairngorm ServiceLocator.
view source

ISQLResponder: ISQLResponder provides a consistent API from which asynchronous SQLStatement execution results and faults can be handled. ISQLResponder is very similar to IResponder in that it defines both a result and fault handler with a slightly different signature which is specific to a SQLStatement result / fault, (i.e strongly typed parameters).
view source

ISQLStatementResource
: ISQLStatementResource is a marker interfaces which is intended to improve code readability by indicating that a class which implements this interface is to provide access to external SQL statements defined in a .properties file.
view source

SQLStatementHelper: SQLStatementHelper is an all static utility class which provides a mechanism for substituting tokens specified in a statement with arbitrary values.
view source

I am also releasing an update to Cairngen (though only a dot release) which supports the AIR Cairngorm API. Cairngen will now provide targets for generating business delegates which utilize the AIR Cairngorm services.

I suspect Adobe will release an updated version of Cairngorm which supports integration with AIR applications. AIR Cairngorm provides an interim solution which developers can use under the terms specified in the License.

I plan to update AIR Cairngorm to support the AIR File system API within the next week or so.

Below I have provided downloads for the source, binary, AIR Cairngen and usage example:
source
example
air-cairngen
air-cairngorm

Adobe AIR SQL interfaces

Friday, June 29th, 2007

I have been working with the new SQL API for Adobe AIR which is available as of Flex 3 beta.

The new SQL capabilities provide numerous possibilities when developing online / offline desktop applications in Adobe AIR which require data to be persisted locally when not connected.

The SQLConnection and SQLStatement classes provide everything you need for working with a SQLite database. The SQLEvent and SQLResult classes provide an API into asynchronous statement executions from which query result and faults can be handled.

After initially working with the new classes I began to recognize the need for some interfaces which could assist in managing query results. With that being said I have created some straight forward interfaces which you can utilize to handle SQLConnection and SQLStatement results in order to handle SQLResults and SQLEvents uniformly.

The ISQLConnectionResponder interface defines a contract for classes that must provide an API which handles SQLEvent objects dispatched via a SQLConnection instance. The ISQLStatementResponder defines the contract for classes which must handle successfull SQLEvents dispatched via a SQLStatement instance. These interfaces are targeted at wrapper APIs for the SQLConnection and SQLStatement classes, therefore as a best practice they should be implemented in a has-a relationship design.

I am also in the process of developing an AIR specific ServiceLocator which integrates into the Adobe Cairngorm framework which will allow AIR application to utilizing the SQLite API to be built with Adobe Cairngorm. This will provide a temporary solution while we await a Cairngorm update which addresses this. As always I will publish the AIRServiceLocator as open source once completed.

Quality API Design: A how to from Google

Sunday, May 20th, 2007

As a lead Software Engineer for a large organization I spend a great deal of my time designing APIs. I spend practically the same amount of time mentoring team members and evangelizing the benefits of a good design.

If you are a programmer than you are a designer; that is, you design class hierarchies and compositional relationships, determine whether an interface or abstract is needed and so forth. This is all part of designing an API, and the more thought you give to your design the better the results will be.

Conceptually, designing a quality API is pretty straight forward: all requirements must be satisfied by the design in a clean and efficient manner. However there are many details involved which you should keep in mind when designing.

Joshua Bloch, Principle Software Engineer at Google has published a very useful article which covers the various facets of good API design. If you are a programmer this is definitely worth reading. Check it out.