You are viewing the Articles published in

Cairngorm moving forward

This week Adobe announced that Cairngorm has been moved to from Labs to opensource.adobe.com.

So what does this mean for you, as a developer, building RIAs targeting the Adobe Flex platform on top of Cairngorm?

It means a lot.

The most significant being that Cairngorm now has a formal community based initiative. This in itself facilitates positive growth as it encourages community feedback and collaboration. It allows the community to have an open podium for discussion, collaboration and most important, knowledge sharing.

So how can you contribute? To begin, start by signing up as a member and sharing your thoughts and experiences. Get involved; engage in conversations with the rest of the community. Take a look under the hood; get to know Cairngorm internals (if you don’t already).

I have a lot of confidence in the future of Cairngorm and I think we can all expect good things to come.

Embedding assets with ResourceBundle

Here’s a quick tip you won’t find easily on live docs…

Yesterday I found myself needing to embed assets in a .properties file (ResourceBundle) however after looking through the Flex documentation I wasn’t completely satisfied with the examples that were available. So I tried something pretty simple and it works perfectly.

To embed an external asset such as an image, audio file, font etc you need only specify an embed directive just as one normally would for an asset, and the file will be embedded in the application. This approach is very much like using the embed directive to embed assets in CSS but only with properties files instead.

For example, suppose you wanted to embed an image named, “image.jpg” using a properties file. To do so simply define the image as follows:

Then to display the embedded image simply reference the class object to which it has been embedded as follows:

And that’s it. Same applies for all embedded assets. I also provided a quick example as well – complete with my son Anthony on the Piano!.

XMLAsset: API for embedded XML files

Back in February I blogged about how to embed arbitrary file types in ActionScript (see “Embedding assets with application/octet-stream” for the complete post). That post was inspired by some work I was doing at the time which involved embedding XML files in ActionScript as an alternative to using the <mx:Model> tag in mxml. In the time since I have created a simple yet useful class which can be utilized as both a utility a concrete or a base class to facilitate decoding an embedded XML file to an XML object.

XMLAsset provides an API which allows for the decoding of an embedded XML file (via the [Embed] metadata tag / compiler directive) to a native XML object. There are three different ways XMLAsset can be implemented, the first of which is to simply create an instance of XMLAsset and pass the constructor a reference to an embedded XML asset as follows:

In the above example we are simply creating an instance of XMLAsset and passing a reference to an embedded XML asset from which to decode to a native XML object. From there we can access the decoded xml object as needed.

The second implementation is to sub-class XMLAsset and pass in a reference to a specific embedded xml file by calling super on XMLAsset, as can be seen in the following:

In the above example we are simply extending XMLAsset and passing a reference of the embedded asset to super. From there we can access the decoded xml object as needed.

The third way to utilize XMLAsset is to invoke the static createXML method directly. To do so we pass in an embedded XML asset just as we did in the first to examples. The createXML method returns a native XML object. An example is as follows:

One thing to keep in mind is if the file which is to be embedded contains XML but does not have the recognized .xml extension the compiler will throw an error. In such cases you need only specify the mimeType as “application/octet-stream” in order to embed the file without error, however I suggest always using the .xml extension whenever possible as in the event the file should contain invalid XML mark-up you will get an error during compilation rather than at runtime. In any case embedding an XML file with an extension other than .xml is very simple, an example of which can be seen in the following:

And that’s all there is to it. Enjoy.

Let design guide, not dictate

A good design should intend to guide implementation, not dictate it; and for good reason as, the dynamic nature of requirements and systems is often too complex to view for a technical design to be considered as anything more than a basic prescription intended to convey the basis for implementation. Yet far too often people seem to believe that once a detailed design has been completed and approved implementation should be a breeze; however, this is just not a very realistic expectation.

For instance, one of my core job responsibilities is to review technical design documents and provide feedback and direction. This is an iterative process which typically has between 1-3 iterations depending on the complexity of the system. Initially myself and an engineer are given requirements for review. He or she then begins an initial draft of the design and once completed passes it on to me for review. I then review the document and provide feedback where applicable, either via annotations to the document itself or by reviewing with the developer (which is by far my preferred process). Should modifications be required the developer will then make revisions as needed. This process is repeated (within practicality) until final design has been approved.

At first it may appear as if only a single design iteration and review would be needed, however more often than not, requirements may not be completely understood during the beginning stages of design, nor are they typically ever set in stone so it is very common that a design will need to change during the early stages of a project or even throughout the entire development stage. Once final design has been completed an engineer then begins implementing the design. Theoretically this may appear to be a quite simple process: create a great design which contains as much detail as possible, review it, make revisions and approve it, then just pass it off to any developer for implementation and that’s it, done, right? – wrong!

There are a number of problems to this approach. Below I have outlined the three I feel are most significant and the solutions I have found to address each.

Creativity

The first problem is that a design which goes into too much detail completely limits or even worse, kills creativity – which in my opinion is the single most important trait a developer can possess, especially when designing. The developer is now merely a typist and will undoubtedly become very bored when implementing the design, especially if it is not even his/her design to begin with! Because of this lack of creativity the final code will ultimately suffer and bugs can be expected. Keeping design on a higher level allows developers to have the creative freedom needed to provide quality implementations and work they can feel is their own.

Flexibility

The second problem is that the more detailed and precise the design the less flexibility there is when requirements change and modifications need to be made to the design and thus implementation. For example, if a design contains very low level details, such as method signatures and other implementation specific details the ability to change the design now becomes increasingly complex and will result in much of the design needing to be reworked significantly. In addition the more detail there is the harder it is to write unit tests against the design as the actual implementation has already been defined. Designs need to be very high level and should not go beyond identifying class names, their responsibilities, relationships and dependencies.

Tools

The third problem is that far too often developers get caught up in all the details of UML notation and related tools. Again, this negates creativity and results in the developer concentrating more on making the design look technically correct rather than concentrating on designing towards a great solution which addresses the problem at hand. In addition, this also results in unnecessary time being spent to complete the design – time which otherwise could have been much better spent on something that produces a better pay off for the project. Now this is not to say that UML shouldn’t be used, actually quite the contrary as I feel a final design should be in UML (or some other format) as a shared language is very helpful in allowing readers to easily understand the design. I always suggest a technique where developers draw out their design in any way that makes sense to them without having to give much thought to anything other than the solution itself. This could be anything from drawing / scribbling thoughts on a pad, to building out a vision from legos – seriously! Only once the design has been envisioned would I recommend bringing it to realization through the use of a formal design tool, such as Visio or other UML tools to be used.

The above illustrates the three most common design issues I have encountered, most of which pertain to over-detailed designs, as well as the approach I take to address each. If you have not encountered any of these issues in your own work than that is generally a good sign, however try to keep them in mind when designing as it will pay off in the end. The important thing to remember when designing is to design for flexibility and simplicity. Less is usually more and the KISS principle, especially when applied to software design, will always pay off in the end.

AIR Cairngorm 2.0

I have received quite a few emails since the release of AIR 1.0 and Flex 3.0 regarding the AIR Cairngorm API which I developed last year. In the time since I have been working primarily with a modified version of AIR Cairngorm which I used on a number of successful real world AIR applications, however I simply have not had the time to document and refactor for general use until recently.

In case you are not familiar with AIR Cairngorm it is an open source project built on top of Adobe Cairngorm which provides a framework for working with the Adobe AIR SQLite API while building an application with Cairngorm.

AIR Cairngorm is built around the SQLService class which essentially wraps the AIR SQL APIs to provide a uniform interface which can be utilized as a service, much in the same way one would work with RPC services in a typical Cairngorm application. SQLService provides an API for both synchronous and asynchronous implementations.

In the time since the initial development and release of AIR Cairngorm, which was during the early alpha releases of AIR, there has been many changes to the SQL APIs in AIR. In addition I have also developed some new best practices for working with Adobe AIR and Cairngorm, all of which I tried to roll into this latest release where possible.

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

AIRServiceLocator: The AIRServiceLocator is a sub class of Cairngorm ServiceLocator, therefore it inherits the same API as ServiceLocator while also adding additional support for working with local databases via the getSQLService and hasSQLService methods.
AIRServiceLocator

SQLService: The SQLService class essentially wraps the SQLStatement and SQLConnection classes. SQLService allows developers to create an mxml implementation defined on a Cairngorm ServiceLocator just as one would with typical RPC services (e.g. HTTPServices, WebService etc.)
SQLService

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 however with a slightly different signature which is specific to a SQLStatement result / fault, (i.e. strongly typed parameters).
ISQLResponder

SQLStatementHelper: SQLStatementHelper is an all static utility class which facilitates substituting tokens in a SQL statement with arbitrary values.
SQLStatementHelper

I have also created a custom version of my Cairngen project specifically targeting AIR Cairngorm code generation. In addition I will be making some future updates to AIR Cairngorm which will include support for various other AIR APIs in Cairngorm, so stay tuned.

Below I have provided downloads to the source, binary, air.cairngen and asdocs as well as asynchronous and synchronous example projects:
source
binary
examples
asdoc
air cairngen
air cairngorm (all)

Implementing interfaces in mxml

Most Flex developers are aware that mxml files are essentially declarative representations of ActionScript classes, that is, during compilation the mxmlc compiler generates ActionScript 3.0 classes from mxml files before being converted into bytecode that runs in Flash Player. This can be seen by setting the compiler argument -keep-generated-actionscript to true.

You may be thinking “yeah I know this, and…”, however in the past week I have had two talented Flex developers say to me: “but you can’t implement interfaces in mxml… Can you?”

Now if you think about that statement a bit more you will probably realize that you most certainly can, however it mat not seem so obvious at first as developers tend to think of mxml for what it is, a markup language and not necessarily from a compilation perspective.

So in case you are not aware how interfaces can be implemented in mxml I have provided a few simple examples below which demonstrate how a custom component can implement an interface, in this case mx.rpc.IResponder.

First you define the interface that the component will implement using the implements property of the component.

Next you simply implement the operations defined by the interface as you normally would in a class:

Now you may be wondering how multiple interfaces are implemented in mxml? This is very easy as well, simply specify the fully qualified class path of each interface as a CSV (Comma-separated values). An example can be seen in the following:

And that’s all there is to it.