You are viewing the Articles in the News Category

AS3 Singletons, revisited

The topic of Singletons in ActionScript 3.0 has been coming up again lately and it has been very interesting to see all of the unique solutions the community has come up with. In particular I like the idea of having Singleton metadata which would allow the compiler do all of the work for us.

Personally I feel the Singleton pattern is extremely useful. It is arguably one of the most common design patterns around today. Practically every management centric API requires a Singleton one way or another. Some developers claim that the Singleton pattern is nothing more than a euphemism for a global variable, to some extent this is true, however the intent of a Singleton is clearly different.

As useful as the Singleton pattern is my biggest complaint about Singletons has always been the actual construction code required to create / protect the Singleton instance. This extra code often becomes quite verbose and it is annoying to have to sift through all of the Singleton code when working with the actual class implementation code. It would also be nice to not have to constantly re-write the Singleton construction and implementation code every time a Singleton is needed.

So is there a way around all of this? Yes!

I developed a simple class called SingletonMonitor which singleton classes can extend to allow the omission of all Singleton specific construction code. All that is needed is to have the class which is to be a Singleton extend SingletonMonitor. That’s it. No more getInstance(), inner classes, type checking and so on is needed. As a best practice I recommend that you define the Singleton instance in the class itself in order to improve code readability.

An example demonstrating how to use the SingletonMonitor can be seen in the following:

As you can see no Singleton construction code is needed. Additionally, by extending SingletonMonitor you are clearly stating that the class is intended to be a Singleton.

So how is this accomplished? It’s pretty simple…

When a derived class is instantiated the SingletonMonitor constructor is invoked, the constructor parses the current stack trace in order to determine the derived class’ name (hence the hack). The name of the derived class is then used as a key in the SingletonMonitor hash table. When a subsequent instantiation of the class is made SingletonMonitor checks the name of the class and if it has previously been defined in the hash an exception is thrown. I originally developed this using introspection to determine the fully qualified name of the class, however the preferred implementation is to have the class eagerly instantiated at compiled time (i.e. constant), thus the stack trace is not available.

Admittedly this is a bit of a hack, but so are the alternatives, otherwise this issue would never have been a topic of discussion in the first place.

However what I like about this new approach is that the Singleton is being managed outside of it’s concrete implementation, and that is the goal of this post; to present an alternative means of managing Singleton construction. Through this the Singleton construction and management code can be omitted as it is being handled by a completely separate object.

So the SingletonMonitor was the first example of how Singleton management can be achieved. The second example demonstrates the Singleton management approach implemented via composition as opposed to inheritance – which is my preferred mechanism of Singleton Management. In addition to creating the SingletonMonitor which utilizes inheritance I also created a SingletonManager which utilizes composition. The SingletonManager is the implementation I recommend and prefer.

An example demonstrating how to use the SingletonManager can be seen in the following:

The SingletonManager requires the class constructor to invoke SingletonManager.validateInstance and pass in a reference of the instance. This is automated in the SingletonMonitor as the class name is determined automatically which is convenient, however the readability of the SingletonManager is preferred as it clearly states intent. Additionally the SingletonManager guarantees the correct type is resolved.

So this is a new way of thinking about Singletons; to provide a management system from which Singleton construction and protection can consistently provided.

To be honest, this was really just an experiment I have been playing around with for some time now that I thought I should share, I am not sure if I would use the SingletonMonitor in production code as the parsing of the stack trace just feels a bit to much like a hack. However I will most likely utilize the SingeltonManager moving forward as it is a great way to abstract Singleton construction and protection from the class implementation.

My hope is that there will be a true solution available as we move forward, but for the time being if you would like to create Singletons without the need for all of the Singleton implementation code feel free to extend SingletonMonitor for management or SingletonManager for compositional management.

Cairngen 2.1

Last week Cairngen 2.0 was released, and judging by my Firestats totals there has been on average, roughly 250 downloads per day.

Based on the feedback I have received so far, the single most requested feature users are asking for is an additional target which will generate multiple Event, Command and Business Delegate classes (Sequences) simultaneously.

Ironically, prior to the Cairngen 2.0 release one of the contributors (I don’t remember who, so if you read this please leave a comment and take credit where it is due) added a few additional tasks which did just this.

So after a bit of fine tuning and testing I have added three new targets which are as follows:

  • create-multiple-sequences-include-delegates
    Generates multiple Event, Command and Business Delegate classes simultaneously. To do so simply assign a comma delimited list of Sequence names to the sequence.name property in project.properties.
    (e.g. sequence.name=Login, Logout, RegisterUser, UnregisterUser)
  • create-multiple-sequences-exclude-delegates
    Generates multiple Event and Command classes simultaneously. To do so simply assign a comma delimited list of Sequence names to the sequence.name property in project.properties.
    (e.g. sequence.name=Login, Logout, RegisterUser, UnregisterUser)
  • create-multiple-value-objects
    Generates multiple Value Object classes simultaneously. To do so simply assign a comma delimited list of VO names to the vo.name property in project.properties.
    (e.g. vo.name=Login, Logout, RegisterUser, UnregisterUser)
  • I have also updated the comments in both the project.properties file and the build.xml files, respectively.

    If you have any additional feature requests you would like to see added to Cairngen, or if you have already implemented these features. feel free to leave a comment or send me an email.

    Download Cairngen 2.1

    Cairngen 2.0

    It has been awhile since the release of Cairngen 1.0, and the feedback I have received from the community has been very encouraging. I am happy to have provided a first-of-it’s-kind utility which allows developers to save time when building Flex applications on Adobe Cairngorm. Additionally, many of you have contacted me with some really cool new features that you have added, some of which are now available in this latest release.

    Objective
    The main objective of Cairngen 2.0 was to address 2 issues which were inherent to Cairngen 1.0. The first being that Event / Command mappings were not automated. In Cairngen 1.0 developers had the ability to generate sequences which consisted of an Event, Command and optional Business Delegate. And although this was very useful as it generated all of the required classes, handled upcasting events and instantiating Business Delegates, developers were still required to implement addCommand() in the FrontController manually. The second issue was that Event types were not generated as uppercase. Event types are static constants therefore they should always be uppercase. This is not required, however it is a best practice. Again developers could easily generate the required Event class but they would have to manually modify the event type to make it uppercase.

    These two issues were the main thing preventing Cairngen from full circle code generation and implementation. Cairngen 2.0 addresses these 2 issues by automating the process, thus allowing for even faster development of Cairngorm projects.

    So what’s new in Cairngen 2.0?

  • FrontController addCommand automation
    Event / Command mappings via the FrontController are now automated. When generating a sequence (Event, Command, Business Delegate) the FrontController will be modified to implement an additional addCommand for the Event and Command. This is achieved by a simple //todo comment which is uses as a token and replaced when sequences are generated.
  • Event TYPE
    Event type constants are now generated as upper case. Additionally the value of the event type is set to the fully qualified namespace of the event, thus preventing it from possible collisions with other Events.
  • User prompted before deleting
    You will now be prompted prior to deleting directories in Cairngen 2.0. You can override this by setting the new “prompt.on.delete” property to false
  • Class file copyright header
    Developers can add a specific copyright header for each class file generated. When specified the header will be added before the package definition.
  • Remote class VOs
    The ability to generate and register remote classes with a VO is now available
  • Logging
    Developers can toggle between logging the console output. This can be accomplished by setting the “log.output” property to true or false
  • What’s next?
    I don’t know, you tell me? If you have additional features you would like to see added to Cairngen, or if you have extended Cairngen to provide these features, feel free to leave a comment on this page. I am planning on adding some new features in the near future. One of which will be the ability to detect duplicate addCommands.

    I would like to thank the many developers who have contributed to the development of Cairngen 2.0. I am in the process of compiling a list of contributors, at which point I will update the release notes.

    Cairngen is licensed under the MIT License.

    Ant and Ant-contrib are licensed under The Apache Software License

    Download Cairngen 2.0

    Configurable ContextMenu API update / example

    I have received numerous requests for an example which demonstrates how to implement the ConfigurableContextMenu API which I had developed back in February of this year.

    In the time since the original post I have re-factored many of the core features, however the goal of the ConfigurableContextMenu API remains the same.

    The following is a brief recap from the original post.

    The ContextMenu classes in ActionScript 3: ContextMenu, ContextMenuItem, ContextMenuBuiltInItems provide a good base for working with context menus in Flex 2, however they do not provide an intuitive API for developing and working with custom context menus, especially at runtime, so in this regard these classes fall short to some degree.

    In order to provide a solution which addresses the issues mentioned above I have developed a ConfigurableContextMenu API which allows developers to dynamically create custom context menus by which items can be added, removed, enabled, disabled, shown, hidden and cloned dynamically at runtime. This API also addresses certain Flash Player restrictions which fail silently in the ContextMenuItem class such as caption collisions and reserved captions restrictions which are simply ignored by Flash Player, leaving the developer clueless (until reading the documentation) as to why the items have not been created.

    Below I have provided links to ConfigurableContextMenu resources which include complete documentation, UML class diagrams and basic example Flex application.

    example
    asdoc
    uml diagram

    The ConfigurableContextMenu API is published under the MIT license.

    MAX 2007 in Chicago

    I arrived in Chicago earlier this afternoon as I will be attending MAX North America from Sunday – Wednesday.

    This is my first time visiting the “Windy City” and it is a really nice place; very clean and very quite for such a large city, or maybe that’s just because I am used to NYC?

    I am staying at the Hilton Towers and the food and drink at Kitty O’Sheas is worth the trip alone. The hotel also has a very interesting historical background as well.

    If you should happen to be attending MAX as well feel free to look me up.

    I am planning on writing a post soon after I return regarding what I feel were some of the more significant highlights of MAX 2007.

    AS3 QueryString API Update

    I have upgraded the QueryString API from an all static utility class to a much more robust API which now supports parsing, inspecting and modifying query strings.

    The new QueryString API retrieves a query string for a Flex application via ExternalInterface. Therefore a query string which has been supplied to an application can be retrieved from an html wrapper (e.g. .html, .jsp, .aspx, etc) as well as a .swf file.

    Developers can also utilize the new API to perform CRUD operations on an arbitrary query string supplied to the QueryString constructor. I have also added complete support for encoding and decoding a query string as well as appending a query string to separate URLs.

    Modifications of a QueryString are now fully supported and allow parameters in a QueryString object to be created, read, updated and deleted.

    The QueryString constructor takes a url as an argument. This argument is optional, and, if specified instructs the QueryString object to use the specified url for all subsequent operations. If the url is not specified the QueryString object will assume the aplication query string is to be used for all operations.

    Unfortunately, ActionScript 3 does not support constructor / method overloading so the url parameter is used to achieve the correct functionality based on context.

    Below is a typical use-case which demonstrates how to instantiate a new QueryString object which defaults to the application’s querystring:

    Optionally, you can choose to use a specific QueryString by passing it to the constructor:

    Additional usage examples for all method can be found in the accompanying ASDoc.

    You can view the source for the IQueryString interface and concrete QueryString implementation as well as the asdocs.

    QueryString API is protected under the MIT license.