Protection – an ActionScript guarding library

by RIAstar on August 15, 2011

I’ve just pushed a usable version of a new library – called Protection – to GitHub. It will enhance the handling of the computing flow of asynchronous programs in ActionScript 3 and make your code look cleaner. (You can use it for synchronous programming too, but there’s less gain to be made.) At this stage it’s very much a work in progress, but the basic event handling is ready for production now. Next stop: enhancing service calls.

This looks like something for me!
If you regularly look at your ActionScript code and find yourself mumbling: “Ah, this class would look nice now, if it were not littered with all these ‘handleThisButtonClick’s and ‘handleThatLoadComplete’s. And then half of them take an ‘Event‘ argument that is never even used in the function. Yuck!“, Protection might be just up your alley.

Don’t mention the war!
If you want your code to be checked as much as possible at compile time and you like to have all your variables nicely typed, please step away from this page. The idea for Protection came to me when I first started mucking around with Ruby, so be warned.

So what’s wrong with my current code?
Let’s have a look at a classic example (warning: I’m going to oversimplify things here for clarity’s sake). Consider the following component:

a simple form

A simple form

It will have to do three things (all pretty straightforward, you may skip ahead):

  • if you click the ‘reset’ button,  the input field shall be emptied
  • if you click the ‘submit’ button the content of the form is validated (i.e. there must be something in the input field and it must be formatted as an email address):
    • if the form is valid, your email address will be stored on my server, so I can spam you
    • if it is not, the form will display an error message and invite you to correct it

If you’re not a very good programmer your code might look somewhat like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class From {

    public var mailInput:TextInput;
    public var submitButton:Button;
    public var resetButton:Button;

    ...

    private function createChildren():void {
        ... //create the visual elements

        submitButton.addEventListener(
            MouseEvent.CLICK, handleSubmitButtonClick);
        resetButton.addEventListener(
            MouseEvent.CLICK, handleResetButtonClick);
    }

    private function handleSubmitButtonClick(
                     event:MouseEvent):void {

        var isValid:Boolean;
        ... //do the validation of the form
            //and set local variable isValid

        if (isValid) {
            ... //send info to the server
        }
        else {
            ... //alert the user about his mistake
        }
    }

    ...

}

Many people would encapsulate the validation part into its own method. I’ve encountered the resulting pattern many, many times in ActionScript code I’ve seen. There’s obviously still too much going on for one function to handle, so some developers decide to encapsulate the two cases each into their own function. This would result in:

1
2
3
4
5
6
7
8
function handleSubmitButtonClick(event:MouseEvent):void {
    if (isValid()) {
        sendInfoToServer();
    }
    else {
        displayErrorMessages();
    }
}

Now you have three distinct functions. Each one of them does only one thing and it is very clear from its name what it is that it does exactly.

Much better!

And yet, I feel sad when I look at this. Because there is one ugly duckling in this class who’s name doesn’t give me the faintest clue of what it does. It only tells me when it will be called, which is frankly useless. And to top things off, it requires a parameter that it doesn’t even really need. Which – besides just being confusing – makes it impossible for me to call that function directly.

Form class outline

The form class outline

This example is but a small component that does very little. Most classes in ActionScript are riddled with these kind of handlers.

Enter Protection
Let me just rewrite 2 lines of the construction code for you, the ones where we added event listeners to the two buttons:

1
2
3
4
5
6
7
private function createChildren():void {
    ... //create the visual elements

    addSentry(submitButton,
        isValid, sendInfoToServer, displayErrorMessages);
    addEnvoy(resetButton, reset);
}

I can now simply remove both handler functions from my code and what remains is a class with a clean outline, less code and much easier to scan too. You may have noticed we don’t even mention the event type anymore. That’s because Protection has some default types mapped to some common classes, which of course you can override. Since on buttons we nearly always want to listen for MouseEvent.CLICK events, I don’t feel the necessity to always explicitly say so. And if you do want to register another type of event, there’s an optional parameter that can let you do just that.

But, but, but, … sometimes I really need that event object in the handler, or at least some property of it…
Never fear, we can fix that in a jiffy. Suppose we wanted to validate the form as the user was typing. We might add the following to the construction:

1
2
3
4
addSentry(mailInput,
    isValid, enableSubmitButton, displayErrorMessages,
    KeyboardEvent.KEY_UP
).mark("currentTarget.text");

So what happens here? Instead of passing the entire Event object to the handlers, a certain property is extracted from the Event and passed only to the functions that require it. For instance:

1
2
3
private function isValid(email:String):Boolean
private function enableSubmitButton():void
private function displayErrorMessages(email:String):void

Of course, you can do more complicated things to suit your needs, although Protection‘s main goal will always be to make code clearer rather than obfuscate it. I will elaborate on the possibilities in ensuing posts since this one is already long enough.

Hey, what about AS3Signals?
I know of AS3Signals of course. It’s a nice, mature library with quite some people working on it and many more using it. And it addresses very similar issues, or at least the same grievances with native AS event handling.

But there is one reason why I’ve never really used it: it totally omits the native event system. I do understand the motivation behind this, but the reality is that I have to use components written by others which dispatch only native events and don’t have Signal properties. Not in the least the entire Flex component set.

So this, in short long, is why I created Protection. You can download it or check the source code on GitHub.

Protection on Github

Leave your comment

Required.

Required. Not published.

If you have one.