You are viewing the Articles published in

Quality API Design: A how to from Google

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.

Running ASDoc against AIR projects

At first glance one might think the ability to run asdoc.exe against an AIR project would be pretty much the same as compiling ASDocs for a typical Flex project – but it’s not.

I recently completed updating my AIRCairngorm project and decided to compile the source code documentation as I always do, however when I attempted to do so my build failed. Based on the exceptions asdoc.exe was throwing it was pretty obvious the build was failing because none of the classes in the AIR API could be resolved.

I did a quick Google search and unfortunately there wasn’t much out there explaining how to resolve the errors. After a little more digging around and exploring of the sdk I was able to fix the build. Basically asdoc.exe needs to point to air-config.xml as well as the location of the air swc’s.

Below is the final build I am using which will allow you to compile ASDocs for your AIR projects:

You will also need the asdoc.properties file to go along with it:

So if you happen to run into this problem in the future you can use the ASDocAntTask project to compile ASDocs for your AIR projects without the headaches.

Using Namespaces to provide context in AS3

Namespaces in ActionScript 3 are particularly useful for providing context in an application. They also provide an added clarity to APIs outside of the typical language specific access modifiers.

For instance, let’s say we have an application which requires slightly different behaviors depending on a specific type of user. If the user is a guest, the application need only display a fairly basic view, however, if the user is an administrator the application must display a slightly more complex view.

Based on the type of user we can deduce context and from this context we can provide a contextual namespace. The contextual namespace can then be utilized to invoke different methods with the same name on an object.

To help facilitate the management of a contextual namespace I have created a ContextNamespace API.

ContextNamespace is a Singleton class which can be utilized to set and retrieve a contextual namespace based on context. Additionally, ContextNamespace implements INamespaceManager which defines various convenience methods for retrieving information about a contextual namespace, comparing a Namespace against the contextual Namespace and comparing a URI against the contextual Namespace URI.

Below is a simple example which demonstrates how to utilize the ContextNamespace API.

The class below utilizes two custom namespaces; admin and guest. Two methods with the same name are defined in the Class, each of which is under a different namespace.

To utilize ContextNamespace to retrieve a reference to the current contextual Namespace is simple.

In the above code a local namespace is defined which references the current contextual namespace used by the application via ContextNamespace.instance.getNamespace(). The local reference is then used to identify the correct namespace from which methods are to be invoked.

For additional examples which demonstrate how ContextNamespace can be utilized to provide a globally accessible reference to a namespace, view the ASDocs.

ASDocs
ContextNamespace
INamespaceManager

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.

IResponder and Cairngorm

My original post on Cairngorm and IResponder had accidentally been deleted while updating my moderations queue, and many of you have contacted me stating that the post is no longer available so I will re-iterate what I mentioned in that post.

For some time now I have been entertaining the notion of abstracting IResponder implementations from Command classes into separate, discreet classes which are intended to handle asynchronous service invocation responses. There has been some talk in the Cairngorm community recently regarding Cairngorm Commands and IResponder implementations so I thought I would share my thoughts on the subject.

Typically most Cairngorm Events are handled by an associated Command. The Command handles the Event by updating a model on the ModelLocator, and / or instantiating a Business Delegate to manage invoking a middle-tier service.

At this point one could argue that the Command has finished doing it’s job – handling the Event. Let’s clarify by taking a look at a formal definition of the Command Pattern:

“The Command pattern is a design pattern in which objects are used to represent actions. A command object encapsulates an action and its parameters.”

From this we can deduce (in the context of a Cairngorm Event) that the Event is the “action” and the Command is the object which encapsulates the handling of the Event (action). The actual handling of the Service response could be considered a separate concern which is outside of the direct concern of the Event and Command, thus requiring an additional object to handle the service response.

However for many developers it is (by design) typical to simply have the Command implement IResponder and also handle the response from the service in addition to the actual Event. This makes sense from a convenience perspective, but not necessarily from a design perspective.

What I have been experimenting with is pretty simple and straightforward. It involves having a completely separate object implement IResponder and handle the service response directly.

Consider the following example in which a specific use-case requires an account log in (could the Login Example have replaced Hello World?). The following classes would be required: LoginEvent, LoginCommand, LoginResponder and LoginDelegate. Utilizing a separate class as the responder is very simple and straightforward and would be implemented as follows:

So far nothing different here, the above Event is just like any other CairngormEvent. Now let’s take a look at the Command implementation.

Based on the above example, the only method which must be implemented is execute(), as defined by ICommand. The implementation of execute() instantiates an instance of LoginResponder and LoginDelegate, the LoginResponder instance is passed to the LoginDelegate as the IResponder instance (as opposed to the traditional approach of the Command being passed).

As can be seen in the following example, the Business Delegate implementation is the same as any other typical Cairngorm Delegate:

The IResponder implementation would be as follows:

That’s pretty much it. Clean, simple, and yes, more code, however this design supports a clear separation of concerns and promotes encapsulation and code reusability. This example is intentionally cut and dry, however if you consider the many other possible implementations such as utilizing Dependency Injection to inject both delegates and responders, than I believe the benefits become quite clear.

At the end of the day it really comes down to personal preference. For me, I always prefer to have more classes which encapsulate very specific concerns and responsibilities. As long as you have a clear and concise, but most of all, consistent design you usually can’t go wrong.

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