ActionScript Design Pattern Samples: The Singleton

Posted in ActionScript, Design Patterns, Flex, How-To on March 10th, 2010 by Kalen Gibbons

I’ve decided to write a short blog series on ActionScript design patterns. This series will NOT contain in-depth discussions about the patterns, when to use them, why to use them, or any of that. Rather, each post will have a working example that demonstrates a pattern in use, and will be accompanied by a brief description of key points. These working samples may serve as a functional reference for myself or anyone else who may find them useful. Enjoy.

The Singleton Pattern

The Singleton Pattern is a very commonly used pattern in ActionScript; Cairngorm’s ModelLocator is one of the most popular examples that people may be familiar with. In short, a Singleton is used when you want to guarantee that only one instance of a class can exist.

Why would you want this? Well, to avoid conflicts for one. Imagine you have an application with a shopping cart, and various items can be added to the cart from different sections of your application. You’d typically want all a user’s products in a single shopping cart. If multiple carts existed each would have their its products, its own total, and it would be difficult (and problematic) to manage them all at checkout. So how could you ensure that only one shopping cart exists, especially if you have multiple developers working on the different sections of the application? The answer is to make the shopping cart class a Singleton, which ensures that only a single instance of the Singleton class can exist.

The Code

So, how can the Singleton pattern ensure that only one instance of a class exists? Simple, limit access to the class’ constructor and require the class to instantiate itself. This is typically done with a private constructor in other languages, but ECMAScript, the current standard that ActionScript 3.0 is based on, does not support private constructors. So instead, we create a class like the following:

  1. Prohibit constructor access: The easiest way to prevent access to a class’ constructor is to require a parameter that only the class itself has access to. In the example, the SingletonEnforcer class is declared in such a way that it cannot be accessed by any class other than ShoppingCart. Then, by requiring the SingletonEnforcer class to be passed into its constructor, the ShoppingCart class ensures that it cannot be instantiated by anything else; it’s responsible for it’s own creation.
  2. Provide a single entry point: Since Singleton classes cannot be instantiated directly, there needs to be an entry point for external classes to request an instance. The getInstance() method serves this purpose. It must be a static method for it to be exposed without requiring an existing instance of the class. This method simply checks to see if an internal instance exists (stored as the instance variable), creates an instance if not, and then returns that single instance.

The Sample

And here’s a working example, you can view the source code here.

Get Adobe Flash player

And that’s it. Please let me know if you have any questions, comments, or suggestions.


Learning Parsley, Part 1: Dependency Injection

Posted in ActionScript, Flex, How-To on November 9th, 2009 by Kalen Gibbons

SpiceFactorys Parsley FrameworkI decided to take a look at SpiceFactory’s Parsely framework for Flex, and I was pretty impressed. When I started to dig into the framework I discovered that although the framework’s documentation was very good, there weren’t many community examples or tutorials for the framework. So I decided to create a short series on getting started with Parsley. The examples in the series will be fairly simple and no advanced topics will be discussed; my aim is to help developers get a jump-start on development, by providing simple examples of working code.

Defining Object Dependencies

We’ll begin by learning how to add dependency injection into an application. First, we need to recognize our object dependencies. In the sample application below, the ContactList view requires the ContactManager model object to provide its data. In Parsley, marking that dependency as an injection point is as simple as adding the [Inject] metadata tag above the property declaration.

Parsley can also inject properties into constructors and other methods, and you can find more information on that here.

<mx:Script>

<![CDATA[

 

import com.kalengibbons.contactsManager.model.ContactManager;

 

[Inject]
[Bindable]
public var contactManager:ContactManager;

 

]]>

</mx:Script>

Creating the IOC Container

Next, we need to tell Parsley where to find the ContactManager class before it can inject it into the view. To do this, we need to add it to the IOC Container, which is responsible for wiring all our dependencies together. The container can be written as MXML, ActionScript, XML, or a combination of the three. For more information on using these methods you can view the documentation here. For this example, we will look at an MXML configuration. To do this, simply create an MXML file with mx:Object as the root tag, and add references to the objects that we will need to wire, like so:

<?xml version="1.0" encoding="utf-8"?>
<mx:Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml"

xmlns:model="com.kalengibbons.contactsManager.model.*">

 

<model:ContactManager />

 

</mx:Object>

Wiring the View

The framework won’t know to look in our ContactList view for injection points unless we tell it to. To do this, we need to also add the view into the IOC Container. There are two ways of doing this. We could explicitly declare it in the container like we did in the previous step for the ContactManager. But for views, Parsley allows us to dynamically wire them by simply dispatching a single configuration event like so:

<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
addedToStage="this.dispatchEvent( new Event(‘configureView’, true) );">

The configureView event tells Parsley that the view should be added to the IOC Container at runtime.

Initializing the Framework

Finally, to put it all together, we need to initialize the framework and provide Parsley with the IOC Container we created. We want to do this as early as possible so doing this on the addedToStage event is common practice. Simply call the FlexContextBuilder.build() method and provide the IOC Container and the root DisplayObject used for wiring (typically the application root).

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"

xmlns:views="com.kalengibbons.contactsManager.views.*"
addedToStage="addedToStageHandler()">

 

<mx:Script>

<![CDATA[

 

import com.kalengibbons.contactsManager.config.ContactManagerConfig;
import org.spicefactory.parsley.flex.FlexContextBuilder;

 

private function addedToStageHandler():void{

// configure the IoC container
FlexContextBuilder.build(ContactManagerConfig, this);

}

]]>

</mx:Script>

 

<views:ContactList width="100%" height="100%" />

 

</mx:Application>

Here is a working example of the code. The application is very simple; when you click the button it simply populates the ContactModel object with data, which is bound to the DataGrid. The key is to notice how the ContactModel has successfully been injected into the view.

You can view the source code here.

Get Adobe Flash player

Points to Remember

  • Dependency injection takes time, and your objects might not be immediately available. In your views, even after the creationComplete event, your objects may still be null. So what you need to do is use [Init] metadata to designate a function for Parsley to run after injection is complete. Using this instead of a Flex event will ensure that your objects are all available and ready for use.
  • Don’t forget to add the application root to the IOC Container, if necessary. Even though you may initialize the framework in the application root, and use it as the view root of the Context, you will still need to dispatch the configureView event if you need dependency injection to take place in the application root.

Conclusion

If you haven’t done so already, please read the Parsley Documentation for more information about dependency injection and the Parsley framework. And like I stated in the intro, I’m new to Parsley myself so if anyone would like make corrections or suggest any best practices, please feel free to do so in the comments.


Tags: , ,

Creating a scroll-to list in Flex

Posted in ActionScript, Flex, How-To on June 1st, 2009 by Kalen Gibbons

Here is an example of how you can create a scroll-to list using the AnimateProperty class. In this example I’m using a repeater instead of a List for simplicity, but for large data sets this would not be recommended.

I have a DataGrid on the left hand side that simply lists the release date and title of several upcoming movie releases. If you click on a row, the list on the right will scroll to the details for the movie selected.

– View application source –

Get Adobe Flash player

The code is pretty straightforward, but there two main pieces to look at. The first is how to use the AnimateProperty class to scroll the list to the desired location. The second, is how to allow the last item in the list to scroll all the way to the top.

Scrolling to an item in the list

import mx.effects.easing.Sine;
import mx.effects.AnimateProperty;
import mx.events.ListEvent;
 
private var scrollAnimation:AnimateProperty = new AnimateProperty();
 
private function scrollToMovie(event:ListEvent):y{

var yPosition:int = movieWrapper.getChildAt(event.rowIndex).y;
scrollAnimation.stop();
scrollAnimation.property = "verticalScrollPosition";
scrollAnimation.easingFunction = Sine.easeOut;
scrollAnimation.duration = 900;
scrollAnimation.toValue = yPosition;
scrollAnimation.play([movieWrapper]);

}

Allowing the last list item to scroll to the top

private function addSpaceToBottom():void{

if(movieWrapper.numChildren > 2){

var lastChild:HBox = movieWrapper.getChildAt(movieWrapper.numChildren-2) as HBox;
var spacerHeight:int = movieWrapper.height – lastChild.height;
if(spacerHeight > 0)

spacerBottom.height = spacerHeight;

}

}

 


Tags: , ,

Performance testing static methods versus instance methods

Posted in ActionScript, Flex, Performance on May 5th, 2009 by Kalen Gibbons

I was creating several static methods at work today and I started to wonder about how static methods perform versus instance methods. So I created a quick test, that simply calls a static method 5,000,000 times and an instance method the same number of times. Both methods are identical, they simply return true, but as you can see from the results, the static method executes 20-50% slower than the instance method.

To test for yourself, simply click the "Test Instance Method" button to run the instance method test, and then when it’s done you can click the button again to start the static method test. Your results for each test are displayed in the DataGrid. All times are represented in milliseconds.

You can view the source of this application here.

Get Adobe Flash player


Tags: , , ,

Custom Printing with Flex, Part 3: Printing Data

Posted in ActionScript, Coldfusion, Flex, How-To on April 1st, 2009 by Kalen Gibbons

In the first article of this series, I discussed how to prevent users from printing directly from Flash’s default context menu. In the second article, I wrote about using the AlivePDF library to create PDFs from your application for printing or saving. Today I will be covering how to print application data from Flex.

The Flex framework comes with several classes to assist you in printing; however, they don’t tend to produce the greatest results. The PrintDataGrid class is probably your best option when it comes to printing data, but whenever I’ve worked with it in the past I’ve always ended up disappointed. Even after formatting, there are always issues; like rows getting cut off and pages breaks in weird places.

There have been talks about AlivePDF offering a Grid class to the library, which may be interesting, but it hasn’t been released and would probably only handle DataGrid data. So the best option I’ve found for printing data is to allow a server to generate a PDF, which can then be sent back to Flex and output however you want.

A great benefit of this option is the ability to easily format the print results. You can use simple HTML and CSS to customize the printout much easier than you could using ActionScript. You can also add custom styles, letterheads, and footers to fit your needs.

Here is an example, you can view the source here.

Get Adobe Flash player

This will work with any server-side script that can generate PDF content. In this demo I am using a ColdFusion script which simply generates an HTML table and returns it in PDF format. You can view the ColdFusion code along with the rest of the source code here.

The data from the server is returned to Flex as a ByteArray. You can take that ByteArray and output it to the user in several different ways:

Using the Browser

Similar to the last article in this series, you can send the results to a server-side script to either display the PDF in the browser or prompt the user to open or save the document. This time, however, the AlivePDF library is no longer necessary since the PDF binary has already been created.

private function generatePDF(pdfBinary:ByteArray, method:String):void{

//result comes back as binary, create a new URL request and pass it back to the server
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var urlString:String = "http://kalengibbons.com/assets/pages/pdfCreator.cfm";
if(method == "inline")

urlString += "?method=inline";

else

urlString += "?method=attachment&name=dataPrintSample.pdf";

var sendRequest:URLRequest = new URLRequest(urlString);
sendRequest.requestHeaders.push(header);
sendRequest.method = URLRequestMethod.POST;
sendRequest.data = pdfBinary;
navigateToURL(sendRequest, "_blank");

}

Save locally from Flash

Thanks to new capabilities in Flash Player 10, you can also provide users the option to save the PDF directly from Flash. This eliminates the need for the second server-side script.

private function savePDF(pdfBinary:ByteArray):void{

var fileRef:FileReference = new FileReference();
fileRef.save(pdfBinary, "yourPrintout.pdf");

}

If you plan to use the save functionality you’ll need to set the “Required Flash Player version” in your project preferences to 10.0.0 or higher or else Flex Builder will complain. You have to remember that only users with Flash Player 10 or above will be able to use this functionality, so some type of version validation is a necessity.

Another caveat is that the save method must be triggered by some type of user interaction, that’s why the sample application prompts for system access before saving. Although the user has clicked the “Print Data” button, that event is lost when the server call is made, so we need another interaction from the user.


Tags: , ,