Building a Flex Application: Chapter 22 - Programming Flex 3
Pages: 1, 2, 3

Utilizing Best Practices

There are lots of ways build Flex applications. This shouldn’t surprise you; there are lots of ways to do most things in life, and building Flex applications is no different. Furthermore, it’s impossible to say there is exactly one right way to build Flex applications, just as it is impossible to say there is just one right way to do anything else. However, you can employ certain strategies that increase your likelihood of success when building Flex applications. We call these best practices, and in the following sections we’ll go into a bit more detail regarding a few of the best practices we consider most important. We strongly encourage you to try these out for yourself. Give them a fair chance; you may later discard some of them, but chances are that more than a few will prove to help you and your teams in the long run.

Organizing Files

How you organize project files can have a tremendous impact of the success of a project. File organization might seem unimportant, but don’t underrate how influential this factor can be. Organizing files well ensures that not only is it easier to find the files and easier for teams to work together, but also you avoid potential naming conflicts and can facilitate source code versioning (see the section called “Versioning”” later in this chapter).



If you use Flex Builder to create Flex projects, you have probably already noticed that Flex Builder provides a degree of organization. Primarily, Flex Builder distinguishes between where it stores source code (.mxml and .as files) and where it stores deployable application files (.swf, .html, and runtime assets). The default names for the directories that Flex Builder uses are src for source code and bin-debug for deployable application files. This high-level structure is important and essential to good project file organization. However, you can do more, and indeed more is required to keep files organized clearly. The following are a few of the key things you can do to organize files:

  • Place all .mxml and .as files (except for the main application .mxml file) in packages. As you’ve learned, Flex treats .mxml files as ActionScript classes, and therefore we can think of them and organize them just like we would ActionScript classes. We generally recommend using reverse-domain names for packages. For example, all the classes and .mxml files for the sample application in this chapter are organized within a com.oreilly package. After the reverse-domain package, we advise using a project subpackage where appropriate. In the sample application, we place all the files in a pf3 project subpackage. Then it is considered a best practice to further organize files into subpackages. For the sample application, we use the following subpackages:

    controllers

    See the section called “Abstracting Common Patterns”” later in this chapter for more information about controllers.

    events

    We use this package for all event types (subclasses of Event).

    models

    See the section called “Abstracting Common Patterns”” for more information about models.

    services

    This package organizes all the business delegate and related classes.

    views

    See the section called “Abstracting Common Patterns”” for more information about views.

  • Place all embedded assets in a directory inside the source files directory. In the sample application, we call this directory assets_embed. This directory can contain .css files, embedded .swf files, embedded image files, and generally any sort of file that might be embedded in the application (as opposed to loaded at runtime). Depending on the number of files, it may make sense to create further subdirectories to better organize everything within the embedded assets directory.

  • Any runtime assets that must be deployed with the application should be organized within the deployable application directory (bin-debug). These files might include .xml files, image files, or any sort of file that the application loads at runtime. Generally, these files should be organized within subdirectories within the deployable application directory.

Using CSS

Flex provides a lot of ways to apply styles to applications. You learned about all of these ways to style applications in Chapter 8, Customizing Application Appearance. This provides a great deal of flexibility in how to style an application, which is both good and bad. It is good in that it provides lots of options. It is bad in that it allows developers and teams of developers to apply styles without a consistent approach or plan.

We find that in general, it is best to apply most, if not all, styles via external .css files. We make exceptions for some layout-related styles such as verticalAlign and horizontalAlign, which we frequently apply inline. However, we prefer to apply the vast majority of styles via external .css files. For the Flickr application, we use only one .css file because the application simply isn’t complex enough to warrant more than one .css file.

If you look at the FlickrFlex.css file, you’ll notice that we’ve organized our selectors to make them somewhat easy to locate within the file. We place the Application type selector first in the file, followed by the rest of the type selectors in alphabetical order. Then we follow the type selectors with the class selectors, also organized in alphabetical order.

Although it is sometimes tempting to apply styles via inline attributes to MXML tags, we’ve found it is far better in the long run to take the extra minute or two to apply styles via external .css. This has several advantages, some of which are as follows:

  • External .css cleans up style-related clutter from .mxml files.

  • External .css allows non-Flex developers to work on styling an application.

  • External .css helps to differentiate between the layout (view/.mxml) and style (.css).

Application Components

Application components are invaluable and cannot be overrated. Large .mxml files or ActionScript classes without clearly defined roles and responsibilities are a good sign that refactoring is necessary. When an application consists of many smaller components, it is often easier to work as a team, to debug an application, and to add new features or make changes to existing features. Too few components, or components that are too large and too complex, make applications difficult to manage. It is generally advisable to err on the side of too many components with responsibilities that are too granular than the other way around. As a rule of thumb, all components should have no more than two or possibly three key responsibilities. If a component has more responsibilities, it should be refactored into several more specialized components.

As we’ll see later in this chapter, we use application components extensively for the parts of the application that we call the views and the controllers. Almost universally, developers use application components for views. Our use of application components for controllers is somewhat less usual, but we think it provides a solution to issues that are unique to Flex. You can read more about views and controllers later in this chapter. You can read more about application components in general in Chapter 9, Application Components.

Versioning

Although versioning may seem like a related practices rather than a core practice, it is nevertheless a core practice that every team should be following for Flex projects. A variety of versioning software tools are available. Some of the most popular are Subversion (which we are using for the sample application), CVS, Mercurial, Git, Team Foundation Server, and Visual SourceSafe (VSS). Every versioning software works slightly differently, and different teams have different philosophies regarding how to manage code repositories. For example, some teams prefer not to add large assets (e.g., videos) to version control repositories, whereas other teams prefer the simplicity of adding everything to one location. What is most important is that you always add all source code to a repository, and you should always keep the repository up-to-date with changes. For the FlickrFlex project and many of our own projects, we like to add everything to the Subversion repository, including source code, Flex Builder project files, runtime assets, and compile time assets (embedded images, fonts, etc.).

Unit Testing

Unit testing involves writing code that runs automated tests on project code. A test will run an assertion that will either pass or fail. A group of tests is known as a suite of tests. When running a suite of tests, you can quickly determine whether code is behaving as expected. If all the tests in a suite pass, it indicates that there is a good chance the application is working correctly. If one or more tests fail, it shows you where you should look to correct a problem with the code. Automated tests allow you to run suites of tests frequently, often every time you make a change to the code for an application. The results of the test will help you immediately identify any problems which new code might introduce.

Unit testing does not require that you use a testing framework. However, using an existing testing framework can greatly simplify writing and running test suites. There are two testing frameworks that we know of for use with Flex: FlexUnit (http://code.google.com/p/as3flexunitlib/) and AsUnit (http://www.asunit.org). We find that FlexUnit is a little easier to use with Flex than AsUnit.

Note

If you’re not familiar with unit testing or FlexUnit, you might find the article at http://www.adobe.com/devnet/flex/articles/unit_testing.html to be a helpful introduction.

Once you’ve starting writing unit tests, you’re likely to ask yourself exactly what you should be testing. Although it might be possible to write tests for every part of a Flex application, we find that it is generally easiest and most effective to write tests for only certain parts of an application. In particular, we find that tests for the following are most useful:

Data model classes that have custom serialization or deserialization methods

For example, if a class has a method to deserialize from XML data, it can be very useful to write a test or tests for that.

Business delegates

These are points of integration that represent relatively high fragility. If the contract with the service changes (e.g., the publisher of the service changes the API), it’s possible that the entire Flex application will stop working correctly. Having good unit tests for business delegates helps you to quickly identify where an error is occurring if a service contract changes or if a service simply goes offline or throws an error.

Utility classes/methods

Any method of a utility class should generally have unit tests.

There is a philosophical approach to software development, known as test-driven development (TDD). This methodology advocates writing tests before writing application code. You then write the application code to get it to pass the tests. Some Flex developers find TDD works well for certain types of classes, such as model classes and business delegates. Other Flex developers don’t find that TDD is well suited to Flex development. We are mixed on the issue of TDD for Flex development, with one of us liking it and the other not. You’ll have to be the judge for yourself.

Note

You can learn much more about test-driven development in the excellent book, Test Driven Development by Example, by Kent Beck (Addison-Wesley).

The sample application has a suite of tests that are included in the com.oreilly.pf3.flickr.test package, and the application also includes a test runner, TestRunner.mxml, to run the tests. You can see that there are two classes in the test package: PhotoTest and FlickrServiceTest. The PhotoTest case runs tests verifying that a Photo object correctly deserializes XML data as it is returned by the Flickr service. From a TDD perspective, it is useful to write this test before writing the Photo class and its deserialization method. Having the test written first can help to verify that Photo does what it is intended to do and that it meets all the requirements placed on it as you write it. However, even after the class has been written, the tests are useful because you can run them to verify that no regressions have occurred as you refactor the application. Likewise, it can be helpful to write the FlickrServiceTest class before writing FlickrService, and yet it is also useful after writing FlickrService to verify that the service works as intended.

Using Blueprints and Microarchitectures

Even with the best practices mentioned in the preceding section, the idea of building a Flex application from scratch can be a bit daunting. Where should you begin? Sometimes too much freedom can be paralyzing. Artists often report that their greatest creativity stems from having boundaries. Likewise, you may find that having structure may provide the right environment for building a successful Flex application. This is the role of a microarchitecture.

Microarchitectures are intended to provide a general guideline and structure for building applications. A microarchitecture doesn’t deal with the specific requirements of a specific application, but rather concerns itself with a philosophical approach to how applications should be structured and designed in general. Microarchitectures provide these oft-needed boundaries and guidelines that help remove the paralysis you might otherwise experience. To that end they can be useful.

Various individuals and organizations promote many microarchitectures for Flex applications. A few of the more popular of these are as follows:

We don’t advocate the use of any one microarchitecture over another. In fact, we don’t really advocate the use of microarchitectures at all. Instead, we recommend that you find a system that works best for you. For the sample application, we are borrowing some of what we consider to be the best ideas from our own experiences building applications with Flex.

Although any one of these microarchitectures might be helpful and useful, don’t be surprised if it is limiting at the same time. The boundaries created by a microarchitecture can provide structure, but they are still boundaries. If you decide to use one of these microarchitectures, it is probably a good idea to follow the rules and build applications exactly as specified by the microarchitecture until you are familiar with the basics and have built several applications successfully. However, at that time you may find it useful to break the rules a little and adapt them to what works best for you. To really take our advice on this matter you’ll probably need to be fairly proficient with Flex and with basic design and architectural patterns before you even start working with a microarchitecture. That’s not because we think microarchitectures are “advanced” or “difficult.” Rather, it’s because we think that to be able to have a critical approach to using a microarchitecture (such that you can learn from the patterns without having to adopt the entire system blindly) you need to have a fair amount of Flex and application development experience first. For the sample application in this chapter, you’ll find that we’re not stressing that you must build your own applications using the same design structure we’ve used. Instead, we’re simply providing one example that uses patterns that we’ve found to be useful for Flex applications.

Pages: 1, 2, 3

Next Pagearrow