2 December 2008
Basic familiarity with ActionScript 3.0 and Flex is needed to understand this article. Experience with object-oriented programming (OOP) will also help you to understand the concepts and practices set forth in this article.
Beginning
Part 1 of this series focused on best practices for setting up your Flex projects. In Part 2, I continue the discussion by outlining best practices to use during the Flex development process. This article contains over 90 best practices for the Flex development process!
In this article, you will learn how to manage assets so that your application's dependencies will be well organized. I will also discuss widely accepted ActionScript 3.0, MXML, and CSS coding standards currently being practiced by the Flex development community. I'll review ASDoc, a tool that you can use to create API language reference documentation as HTML from your application's source code. In the application architecture section of this article I'll show techniques that you can use to help define the blueprints for your application's foundation. I will cover some of the application development frameworks that are available to Flex developers and discuss when it makes sense to use them and when it does not. Lastly, I will cover best practices for unit testing so that you can test your codebase and ensure the code will perform consistently.
Following these best practices will help you navigate and scale an application's codebase with speed and ease, rather than aimlessly traversing through source code and constantly adding ad hoc fixes.
Let's get going!
Flex applications typically incorporate a collection of files, including several different types of media, such as images, CSS files, fonts, audio clips, and video, to name a few. Keeping the application's assets and source code organized can save time when requests to change the software later surface. Here are some general guidelines to consider when naming and storing the files associated with your Flex application.
Create and use an "assets" directory
The common best practice is to create a folder titled "assets" and store it inside the src directory. The src directory is created by Flex Builder during the Flex project setup.
Thus, the root of your asset directory path will be: src/assets
Use subdirectories inside the assets directory
To help organize the many type of media your application can use, I recommend that you organize subdirectories logically based on the types of media files in use. The following points highlight some commonly used practices for subdirectories.
Use a SWF directory
Consider keeping the SWF files in your Flex application stored in a directory named "SWF". You may want to use a different directory depending on the purpose of the SWF files being loaded into the application. Modules, for example, may be kept elsewhere. Modules are beyond the scope of this article but more information can be found here: Writing modules.
The SWF directory path will be: src/assets/swf
Use an images directory
Store image assets such as JPG, GIF, or PNG files in a directory named "images".
The image directory path will be: src/assets/images
Use a fonts directory
Flex applications can contain embedded typefaces. When using nonstandard fonts for your Flex application store the TTF files and other font files in a directory named "fonts". Also keep in mind that font availability varies across platforms. Including the fonts is a good idea especially if the development team works on different platforms.
The font directory path will be: src/assets/fonts
Use an audio directory
Audio is a commonly used media type in rich Internet applications. Store audio assets such as MP4 and WAV files in a directory named "audio".
The audio directory path will be: src/assets/audio
Use a video directory
Store videos in a directory named "video"
The video directory path will be: src/assets/video
Use an XML directory
If your application contains XML configuration files or XML files that will be loaded directly into the application without making a call to a server, keep them grouped together in a directory named "xml".
The xml directory path will be: src/assets/xml
The directory structure shown in Figure 1 illustrates these conventions.
When authoring the source code for your application, there are several practices that you can use to help keep an application's codebase organized and readable. These will help other developers work on the application later. They can also help you remember how code works if you are required to modify the code in the future.
Best practices for using packages in development
Don't use verbs, adjectives, or adverbs for package names
These should be avoided when naming packages. Use pluralized or concept nouns.
Use plural names for packages
The name for a package containing multiple classes should be pluralized, for example, "effects".
Name packages according to the classes they contain
For example, if your application contains a collection of custom button classes you could create a package named "customButtons" for them.
For more best practices for packages see Flex best practices – Part 1: Setting up your Flex project. For additional practices to consider when creating packages, see Flex SDK coding conventions and best practices.
Best practices for classes
Minimize the amount of executable code defined in the class body
Keep the executable code encapsulated in methods.
Match instance variables to arguments
If the constructor was created to accept arguments and they set instance variables then you should match the argument names to the internal property names.
Follow the classic general conventions when creating classes
Class names should be singular objects within your application. Objects should have singular-noun-based names in UpperCamelCase. For example, if I were writing an online shopping cart system I might name two of the classes ShoppingCart.as and Customer.as. You should also avoid particularly large classes.
Append class types (formatter, validator, event, and error) to the class name
For formatter, validator, event, and error related classes append the type of class to the end of the class name. For example, use ServiceConnectionError, ServiceConnectionEvent, ServiceResultsFormatter, and ContactFormValidator.
Append the skin type to the class name
When creating classes related to skinning, append the type of class to the end of the class name. For example, use SubmitButtonBackground, SubmitButtonBorder, and SubmitButtonIcon.
Consider appending "Base" to superclass names
For class relationships that use inheritance consider appending "Base" to the class name. This can be seen in the Flex framework in classes such as ListBase. This practice is followed when the superclass is considered abstract.
Use blank lines in between methods
All methods in the class should be separated by a blank line. This increases code scannability and code readability.
Code to an interface when possible
If the class you are creating will be part of an inheritance relationship, try to create your class as a concrete representation of an interface. In this context, interface refers to an ActionScript interface, not the user interface.
Best practices for variables
Use meaningful variable names
One-character variable names should generally be avoided. Abbreviated variable names should also be avoided.
Choose descriptive variable names
The compiler will optimize these for you anyway, so the length does not affect file size. Well named variables and functions will make the code easier to read and require the developer to write less documentation.
One variable declaration per line of source code
Try to avoid multiple variable declarations and assignments in a single line of code. Developers can easily overlook a declaration when there are several on a single line.
Separate each variable declaration with a blank line
To improve source code readability, each variable should have an ASDoc comment directly above it; the variable declaration should follow the comment, and a blank line should follow the declaration.
Comment each variable using ASDoc style comments
Describe the reasoning for the variable. Try not to restate the purpose of the variable, instead strive to describe how it is used. See the example ASDoc comment in the Commenting ActionScript source code for ASDoc section of this article.
Avoid the generic name "object"
Avoid using "object" in your variable names. Instead, give more meaning to the identifier.
Always strongly type your variables
Even if the type is * (no type), strongly typing your variable can help show the intention of the variable. The type can help to convey the variable's use and purpose. A strongly typed variable has a predetermined data type and can contain data of that type only (unless the type is changed).
Prefix Boolean variable names with "can", "is", or "has"
This practice can help to quickly identify and differentiate the Boolean variables from other variable types; for example: canAnimate, isConnected, or hasChildren.
Capitalize constants
Constant variables should be in all CAPS with each word separated by an underscore; for example: REMOTE_SERVER_URL, APPLICATION_ID, and DISCLAIMER_TEXT.
Constant variables are values that will not change during the execution of the application. By capitalizing them you can differentiate constants from regular (non-constant) variables.
Match constant string variable names to their contents
If the constant is a string, then match the constant variable name to the string contents. For example, the string "dataEvent" should be in a constant variable named "DATA_EVENT".
Prefix variables with underscores for getter/setters
Prefix variables with an underscore if they will be modified through getter/setter methods.
Include a verb in method names
Methods usually perform an action of some kind on an object of some kind. Use the name of the action in the method name; for example, saveUser or parseXML.
Limit code to one statement per line
Refrain from placing multiple statements on one line.
Group methods in a class by functionality
When possible, group the methods in your classes by responsibility instead of scope. Related methods should be placed together to improve code understandability and readability.
Place the getter method above the setter method
When creating getter/setter methods place the getter method first.
Comment each method using ASDoc style comments
In your comments, explain the reasoning behind the need of the method and describe the usage details for classes that might be calling the method. Explain the "why" instead of restating what the method does. See the example ASDoc comment in the Commenting ActionScript source code for ASDoc section of this article.
Always provide a return type even if it is void (returns nothing) or * (any type)
Provide a return type for all of your methods. A method's purpose can be better understood by looking at the return type.
Always use an access modifier for method signatures
Always use an access modifier for method signatures: public, private, protected, internal.
Specify types for method arguments
Provide a type for all method arguments. This can help developers as they write code that will call the method.
Name the arguments of event handlers "event"
This helps to differentiate the event handlers from other code in your application. Other standard argument names are e and evt. Like most standards just agree on one way of doing things and stand by it.
Do not use spaces to separate method names from parentheses
Strive for clean, uniform, and standardized source code.
Use blank spaces to separate keywords from parentheses
When setting up if, for, case and while statements, place a blank space between the keyword and the parenthesis; for example: while ().
Organize ActionScript classes
Keep ActionScript classes organized and arranged in a way that is consistent with the rest of the source code throughout your application. This will help later when you or another developer needs to locate a particular area of the code to make a quick change.
You can use the following structure as an example:
Indent each new block of code by four spaces
Set your editor to insert spaces instead of tabs when you press the Tab key. This will help avoid cross platform source code display and readability issues. Tabs are displayed differently on different operating systems.
Separate each method in a class with a blank line
Create each method with an ASDoc documentation comment directly above the method. Follow this with the method signature with typed arguments, if arguments are present, then the method body, and finally a blank line.
Use spaces to improve code readability
In general use one space after commas. Use spaces before and after operators such as + and -.
To help maintain consistency and order, use the following practices when authoring or editing MXML source code in a Flex application.
Organize element attributes
Order the element attributes: property, events, effects, styles.
Place the ID attribute as the first attribute
For example: <mx:Button id ="thisButton" />
Group associated attributes together on one line
For example: paddingLeft, paddingRight, x, y, etc.
Group related attributes
If there are more associated attributes than will fit on one line, then use an additional line but keep the related attributes together as best as possible.
Use blank lines to organize MXML
Place a blank line between unrelated groups of MXML elements, such as elements defining transitions and an HBox that controls application layout.
Organize MXML documents
Use a consistent structure to organize your MXML; for example:
Styling and skinning information can become difficult to navigate and understand if it is not written with coding standards in mind. Here are some best practices for CSS that you can use during Flex development.
Avoid in-line CSS
Use styleName and custom class definitions rather than defining styles on MXML elements.
Minimize and clean up your CSS
Keep your CSS in an external file and pull it into the main application MXML file. Avoid embedding styles in MXML code whenever possible.
Group similar style definitions
Organize similar styles in your application's CSS file by grouping them together. For example, group all text-related styles together or group styles for views together.
Comment the styles
Comment the styles to help others who will need to make design changes later.
Limit CSS declarations to one per line
Limit your CSS to a single style definition per line. This improves the readability of the CSS.
Use class selectors instead of type selectors when possible
Try to define custom classes instead of overriding the default styles for the Flex controls. This requires setting the styleName properties on the controls but allows for greater flexibility later.
Use lowerCamelCase for class selector names
This is a community-wide best practice and should be followed.
Avoid using underscores in class selector names
This is another community-wide best practice and should be followed.
Avoid naming class selectors based on appearance
Make an effort to name class selectors based on their function not their visual appearance.
For example, use warningText instead of yellowText, and use errorText instead of redText
If you use yellowText,when the warning text color changes then the name no longer describes the result. The name should not be hardcoded to the appearance.
Use a consistent naming system
Use consistent naming conventions for your styles.
Placing comments in source code helps explain what the code does and why it exists. Using ASDoc is an excellent way to create and maintain living documentation for a codebase. You can use the comments that reside in the code to facilitate code updates and also to produce the documentation using the ASDoc tool.
Note: In some cases, high-pressure deadlines make it impossible to thoroughly comment your code during the software development process. When deciding if you should skip commenting, weigh the benefits and drawbacks for your project and your current situation.
Follow the standard ASDoc commenting format used below:
/**
*
* ASDoc documentation comment.
*
* <p>Another chunk of information related to this code block.</p>
*
*/
Use white space and leading asterisks to make comments more readable
Tidy up the comments so they do not clutter the source code. This improves readability for other developers working with the source code.
Use supported HTML to format the ASDoc output
Use any of the HTML tags that ASDoc supports to improve the readability of documentation comments rendered via the HTML files that ASDoc creates.
Write a complete and concise first sentence of the main description
The first sentence of the main description of the ASDoc comment should contain a concise but complete description for the item being declared. This sentence will be used to populate the summary table at the top of the ASDoc HTML page for this item's class.
Create useful comments for each and every class
Place the comment directly above the class declaration. Outline the code's functionality and note any relationships to other classes. Describe why inheritance relationships exist.
Use @private for hiding classes from ASDoc
If the class should not be documented use the @private tag anywhere in the comment.
Use @return if the method has a return type
If a method has a return value, use @return to provide an explanation of the value being returned.
Use @see for items that have relationships
If the item you are commenting has relationships to other classes or packages use the @see tag to explain these relationships.
Do not use special characters in ASDoc comments
ASDoc will fail if your code contains non-UTF-8 characters.
Comment text should always precede any @ tags
If the comment text is not placed above the @ tag it is interpreted as an argument to the @ tag. The @private tag, however, can be placed anywhere in the ASDoc comment.
Describe how the variable will be used
Create comments that contain useful information about how the variable will be used. Describe the "why" rather than the "what".
Create useful comments for all methods and interfaces
Place the comment directly above the method declaration. Outline the method's purpose and any implementation details. Try to avoid simply stating what the method does. Optionally explain the reasoning for the method's return value and also any arguments the method may take.
Use fully qualified classpaths for event types
This will ensure that the event is completely unique and that it will not collide with events from elsewhere in the system. For example, consider a project in which you add third-party code is added to an application; using fully qualified classpaths ensures that your application's events are unique.
For example: com.seantheflexguy.burrow.events.RSSDataEvent
Flex applications are complex systems that greatly benefit from thoughtful planning. Use proven methodologies to ensure the application being built is structurally sound.
Create use cases
Generate use cases for each goal or task in the application. Define the use cases from the perspective of an Actor. Typically, an Actor is simply a user of the application you are building. A use case can be created around any interaction that a user performs. Actors can also be the application itself, another application, or an outside system such as a web server.
Consider using UML
Describing the application's main classes and data model using the Unified Modeling Language (UML) can help refine the objects in your application and avoid potential rework to the code later.
Consider using code generation
There are a number of tools that will generate ActionScript 3.0 source code from UML diagrams. This can save time in some cases. Two tools worth investigating are Enterprise Architect from Sparx Systems and the free Violet ActionScript 3 Generator (VASGen).
Consider using design patterns
Two great books to have in your library are: Design Patterns: Elements of Reusable Object-Oriented Software and Head First Design Patterns.
Using a framework you will greatly increase your chances of success, especially if your application contains a substantial amount of source code.
Consider using an application development framework
There is some disagreement about whether or not frameworks should be used when developing Flex applications. For enterprise level applications, as well as in teams of developers, frameworks are more generally recommended. My personal preference and recommendation is to use an application development framework. This enables a common language for the architecture of a codebase and provides direction for application development and scalability.
Use frameworks for team-based development efforts
Frameworks help teams to work together in a unified effort and can reduce the chances of duplicating development efforts.
Mate
Mate (pronounced "mah-tay") is a tag-based application development framework created for use with Flex. Mate is an unintrusive framework that allows for a loosely coupled codebase.
Cairngorm
Cairngorm is the de facto standard for Flex application development. If you don't already know Cairngorm you should definitely consider learning it. For more information on Cairngorm, check out this great Introducing Cairngorm article. Adobe Consulting uses Cairngorm and fully stands behind it for their development efforts.
PureMVC
This is a pure ActionScript 3.0 Model-View-Controller application development framework. Futurescale, the makers of PureMVC, describe it as follows: "PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern… The PureMVC framework has a very narrow main goal: to help you separate your application's coding concerns into three discrete tiers; Model, View and Controller."
Other frameworks
There are numerous other application development frameworks that can be used in conjunction with Flex or even just straight AS3 projects.
Know when NOT to use a framework
There are times when a framework is simply overkill for an application. If you are the sole developer of an application and you will be the only developer of the application for its lifetime, then you may not benefit from a framework. If you're developing something very simple, such as a banner ad, you can also skip the framework. The robust feature set offered by an application development framework is often not needed for very simple applications with limited data manipulation and minimal events. For another perspective, see this classic blog post by Steven Webster on the topic of when and when not to use an application development framework.
Unit testing can ensure the quality of your codebase. Writing test cases can lead to more reliable and better code. Testing your code will help find errors and save debugging time. Here are a few best practices that can be applied when implementing unit testing.
Test behavior instead of testing methods
Writing code to test private methods is not always needed. This should be evaluated on a case by case basis. Write code to test against an object's public API. Typically private methods are used internally by a class to support its public API.
Apply the "too simple to break" rule
Don't over test the codebase. If the method is a very simple one line method, like a getter method, don't worry about writing a test case for it.
Use standard OOP best practices in test cases
Follow the same OO methodology you use to write the rest of your application. Refactor test cases to move common functionality into base classes as appropriate.
Use clear and concise test method names
Follow the same method naming conventions used elsewhere in the application's codebase. Avoid generic names for test case methods. This helps other developers easily understand the relationship, responsibility, and purpose of the method.
Write simple test case methods
Keep test cases simple and limit the decisions that are made within them.
Use static values in the assertion method calls when possible
This reduces the chances for error in your test cases and improves the maintainability and understandability of the test code.
Document the test code
Add comments that explain what is being tested and why. Also, outline any special circumstances regarding the test.
Create independent unit tests
Each unit test should execute a single behavior for each method.
Limit assertions to one per test case
Multiple assertions in a single test case can lead to performance issues. In addition, if one assertion fails the other assertions will not be executed until the first assertion passes.
These practices can be applied to all of your Flex applications. Take a moment to review these practices:
Create and use an assets directory
Use subdirectories inside the assets directory
Use a SWF directory
Use an images directory
Use a fonts directory
Use an audio directory
Use a video directory
Use an XML directory
Don't use verbs, adjectives, or adverbs for package names
Use plural names for packages
Name packages according to the classes they contain
Use classes to promote OOP
Use nouns for class names
Minimize the amount of executable code defined in the class body
Match instance variables to arguments
Follow the classic general conventions when creating classes
Append class types (formatter, validator, event, and error) to the class name
Append the skin type to the class name
Consider appending "Base" to superclass names
No spaces in class names
Use blank lines in between methods
Code to an interface when possible
Interface names should be adjectives
Use meaningful and descriptive variable names
One variable declaration per line of source code
Separate each variable declaration with a blank line
Comment each variable using ASDoc style comments
Avoid the generic name "object" for variables
Always strongly type variables
Prefix Boolean variable names with "can", "is", or "has"
Capitalize constants
Match constant string variable names to their contents
Include a verb in method names
Limit code to one statement per line
Group methods in a class by functionality
Place the getter method above the setter method
Comment each method using ASDoc style comments
Always provide a return type even if it is void (returns nothing) or * (any type)
Always use an access modifier for method signatures
Specify types for method arguments
Name the arguments of setter methods "value"
Name the arguments of event handlers "event"
Do not use spaces to separate method names from parentheses
Use blank spaces to separate keywords from parentheses
Organize ActionScript classes
Indent each new block of code by four spaces
Separate each method in a class with a blank line
Use spaces to improve code readability
Organize MXML element attributes
Place the ID attribute as the first attribute for MXML elements
Group associated attributes together on one line
Group related attributes for MXML elements
Place metatags above the property or method that they are marking
Use blank lines to organize MXML
Organize MXML documents
Avoid in-line CSS
Minimize and clean up your CSS
Group similar style definitions
Comment the styles
Limit CSS declarations to one per line
Use UpperCamelCase for type selector names
Use class selectors instead of type selectors when possible
Use lowerCamelCase for class selector names
Avoid using underscores in class selector names
Avoid naming class selectors based on appearance
Use a consistent naming system
Follow the standard ASDoc commenting format
Use white space and leading asterisks to make comments more readable
Use supported HTML to format the ASDoc output
Write a complete and concise first sentence of the main description
Create useful comments for each and every class
Use @private for hiding classes from ASDoc
Use @return if the method has a return type
Use @see for items that have relationships
Do not use special characters in ASDoc comments
Comment text should always precede any @ tags
Describe how the variable will be used
Create useful comments for all methods and interfaces
Use fully qualified classpaths for event types
Create use cases
Consider using UML
Consider using code generation
Consider using design patterns
Consider using an application development framework
Use frameworks for team-based development efforts
Know when NOT to use a framework
Test behavior instead of testing methods
Apply the "too simple to break" rule
Use standard OOP best practices in test cases
Use clear and concise test method names
Write simple test case methods
Use static values in the assertion method calls when possible
Document the test code
Create independent unit tests
Limit assertions to one per test case
Having delivered multiple presentations on Flex best practices, Ted Patrick offers the following perspective, which I think is applicable to this article as well:
"Every project targeting Flex is different, and thus best practices vary depending on the team involved and the project at hand. I have seen all manner of project practices that work for small teams but fail for larger teams and vice versa. This is my take on Flex best practices from having looked at many projects over the past three years. In many ways, my recommendations should not come as a surprise, as these are tenets of classical software development."
For more information on Flex best practices, see:
Thank you very much to the following people for their input and review of this article. It would not exist without their help: Hong Qiu, Dolores Joya, Jens Chr Brynildsen, Jesse Warden, Ben Dalton, Frederic Cox, Colin Loretz, Jack Wilber and Kai Koenig. (I started getting really interested in programming best practices after reading The Visual Basic Style Guide by Tim Patrick. It's worth a read; check it out if you get the chance.)
Full credit to the sources of inspiration and information for this article:

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License