Pages

April 28, 2009

I became a developer so I could build things. I was tired of attending misguided meetings, writing requirements documents that nobody read and talking about what a group of uninformed individuals thought needed to be built. I just wanted to build cool stuff and provide immediate value.

Unfortunately, I quickly learned that application development involves more than writing code. Successful application development is a process involving multiple phases and multiple participants with a range of skills.

To succeed, it’s important to adopt a development process that works for your team, your company and the types of projects you’re involved with. Without a process, the risk of project failure is high. The ideal process doesn’t get in your way, covers only the necessary bases and gives you the best chance for success.

In my experience, I’ve found a "front-end first" approach coupled with small design and development cycles (iterations) to be enjoyable, effective and efficient.

In this blog entry, I will outline the process, tools and platform I use to define, build and deploy small to medium-sized rich internet applications (RIA) using Adobe Flex, ColdFusion and MySQL. This process is neither revolutionary nor specific to RIA development. In fact, many of the steps I follow may also be applied to traditional web development (HTML, CSS, JavaScript, PHP, ColdFusion, .NET, etc).

In addition, to effectively demonstrate the process, I will reference the project artifacts created for each phase of a recently completed Flex project: FlexWire Demo App.

Process

The steps involved to create an application cross 5 phases:

Application planning

Application user interface (UI) layout and structure

Application design and development

Application testing

Application deployment

Application Planning

Entrance criteria: An idea, a directive, an opportunity, a problem, whatever...

To satisfy the business objectives, an application must support a range of user and system scenarios. User scenarios help define the functionality required of an application from a user perspective. Think about the tasks involved in achieving the business objectives. These become your user scenarios.

Step#2: Define user scenarios

It is important to group or categorize user scenarios in a logical manner to minimize confusion and support the UI layout and structure phase. These categories may turn out to be synonymous with user roles.

Application UI layout and structure

After the planning phase, we should have a good understanding of the application’s purpose. However, the UI layout and structure phase will help us flesh out additional requirements while designing each view of the UI.

A view represents a unique combination of Flex UI components (containers and controls) and business logic utilized to perform a group of related tasks. By organizing our user scenarios into logical groupings (i.e. user roles) during the planning phase, the characteristics of each UI view should be somewhat evident.

Preliminary design of each view is attained through mockups. Iterations occur until each mockup accurately reflects the layout and structure of the proposed view and visually demonstrates the functionality required to perform the desired tasks.

Step#1: Create UI mockups

By following this approach, we design the UI while uncovering functional requirements overlooked in the planning phase. New user scenarios discovered during this step should be documented.

Each mockup should represent a unique view of your UI. However, as the number of permutations increase (through view states or navigation containers), this may not be feasible. Use your best judgment.

Note: It may be necessary to supplement your mockups with notes to provide details that may be difficult to capture in a visual mockup. For example: "The contents of ComboBox #2 (US Cities) depend on the selectedValue of ComboBox #1 (US States)."

In addition to UI mockups, it is important to discuss the relationship of each view to one another. This can often be accomplished by building a simple wireframe. Wireframes may also be used to dictate application workflow if applicable.

Step#2: Create application wireframe

Once a wireframe is complete with the supporting mockups, we will have a solid understanding of the project’s scope and the flow of the application. Only now can an accurate development estimate be derived.

Thanks to our wireframe and mockups, we know what needs to be created and how the features are organized within the application. However, before any code can be written, a suitable application platform must be in place.

Step#1: Set up your application platform

A suitable platform includes a separate environment to support your development, testing and production activities. At a minimum, I would recommend 3 environments:

Development environment (created locally for each designer / developer)

Staging (testing) environment

Production environment

To maintain consistent and predictable results, it is important to ensure that each environment is identical from a configuration, code and data perspective.

Note: Environment setup includes, among other things, configuration of a web server, application server and a database server. Initial setup, frequent synchronization and ongoing maintenance of each environment can prove to be very time consuming. I prefer to offload these activities if possible. Maybe you have a server engineer at your disposal. If not, I've found Stax.net to be a great option for quickly and easily setting up and replicating Java server configurations (including ColdFusion) across multiple environments. Stax is a fully-managed platform deployed and hosted on top of Amazon's EC2 cloud computing service.

With each environment in place, a source code repository is required. I won't go into the benefits of source control, however, suffice it to say that without source control you are taking an unnecessary risk while limiting developer productivity. Whether you are working with a team or not, setup a Subversion (SVN) repository and start importing source code from the start.

Note: For RIA development, it is only necessary to import source code files into your SVN repository. The files generated from a Flex release build (release build artifacts such as the application SWF and the wrapper HTML) should not be captured in source control.

With a platform in place, a foundation for development must be established. Architectural frameworks provide a starting point for development and enforce consistent development practices. Many architectural frameworks also support an MVC architecture. MVC is a standard for building RIA applications.

Step#2: Establish an architectural framework

Without a framework, developers can spend a lot of time on the “plumbing” of an application. This is no longer necessary as there are a number of free solutions available. For RIA development, I choose to use Cairngorm on the client-side and ColdSpring & Transfer on the server-side.

With a framework in place, we are ready to finally write some code.

Step#3: Architect and design the user interface (the V in MVC)

Sticking with the "front-end first" approach, build the UI layout and structure by replicating each mockup in Flex using MXML and ActionScript. You'll find that most of the code written in this step will include MXML as it is the preferred method for defining application layout and structure. Also, apply any necessary UI effects and transitions.

Once the layout and structure of the UI is in place, style and/or skin the user interface via CSS and/or ActionScript. This may involve multiple iterations to secure the right look and feel.

UI development should occur within the development branch of SVN (typically SVN trunk) - specifically in trunk >> Flex according to this example.

While building the UI, additional requirements may be uncovered. This is unavoidable. Be sure to document them as they may have an impact on your delivery schedule.

Note: During this step, use of ActionScript should be limited to view logic (i.e. navigating and/or changing view states) and/or styling/skinning. Business logic should be implemented during the next step. Also, in some instances, your UI may require data to achieve the proper look and feel. Hard-coded data structures can help populate data provider controls (i.e. ComboBox, DataGrid, List, Tree, etc) with little effort.

Once the user interface is in place and approval has been obtained, it is time to build out the features of the application.

Step#4: Develop and unit test application features (the M&C in MVC and the application services (the service layer))

Each user scenario defined during the planning phase or discovered subsequently represents a feature of your application. Features should be packaged into short iteration cycles (2 weeks or less) and prioritized. It’s important to identify dependencies as well when determining iteration schedules. For example, Feature B depends on Feature A.

With an iteration schedule in place, feature development can begin. Feature development typically requires use of:

ActionScript and MXML for the controller and model layer within the Flex client

ColdFusion (or any other server-side scripting language) and SQL for the application service layer (Note: Transfer will take care of the majority, if not all, of the SQL required to perform basic CRUD operations)

Each feature will include a set of classes - ActionScript classes and/or ColdFusion classes (CFCs). A unit test for each class is required to validate expected behavior. It is much easier to identify and resolve errors at the class level rather than the feature or application level. FlexUnit and MXUnit can help with ActionScript and ColdFusion unit testing respectively. Unit tests should be performed locally in the development environment. Once all unit tests are successful, "developer" testing should occur to verify the overall behavior of each new feature.

The completion of each iteration delivers a set of fully-functional features from the UI all the way to the database. At this point, code should be copied from the development branch (SVN trunk) to a new branch created specifically for the current iteration. The contents of this new branch should be deployed to the staging environment for additional testing (see next phase).

Each development cycle (iteration) yields a new SVN branch. For example:

Application testing

A former boss of mine once asked me why testing was necessary. He told me "if you built it right in the first place, testing was unnecessary and only a waste of time." Technically, he's correct. Unfortunately, most (if not all) developers rarely get everything "right" out of the gate so I'll dismiss his ignorant comment.

Although each class has been tested at an atomic level via unit testing and the functionality of each feature has been verified, unforeseen behavior can and does occur once ALL of the pieces are put together.

Test each feature in the context of the entire application in the staging environment. Also, regression testing is often required to ensure that new functionality does not break existing functionality. Regression testing can be time-consuming and mind-numbing. Therefore, automated test tools are essential. Look into FlexMonkey and the Selenium-Flex API.

Bugs found in the staging environment will need to be logged in Trac and fixed immediately. Fixes should be applied directly to the code found in the iteration branch. Once bug fixes are verified and testing of the iteration is complete, merge the changes back into the development branch and create an SVN "tag" (snapshot) representing a clean and functional version of the iteration branch. Each tag represents a candidate for release and, if appropriate, may be deployed to production (see next phase).

Note: Development should never occur within a tag.

Staging is also a good place to perform User Acceptance Testing (UAT) if desired.

Exit criteria: Test cases and results; a tag for each successfully-tested iteration; bug fixes merged back into the development branch (SVN trunk)

Application deployment

With each iteration complete and tested, it is time to deploy your application to production. Automation of this phase can save time and minimize errors. Build scripts (ANT or Maven) can perform the following deployment activities:

Exit criteria: A fully-functional application inline with the user requirements, deployed to a production environment, and backed-up in a source code repository

Afterthought: In an attempt to redefine the designer / developer workflow, Adobe is proposing an approach to application layout and design involving a designer's use of existing Adobe tools (Photoshop, Illustrator, Fireworks) to generate the design and layout of each view and, with the release of Flash Catalyst, supplement these design assets with visual effects and transitions. The output being the front-end of a Flex application inline with the designers vision, ready for development and abstracted from the application code in the form of design components. I have yet to explore this approach and currently rely on mockups, MXML, publicly-available themes and styles / skins implemented through conventional CSS and ActionScript to create the layout, structure and style of a Flex application. See related blog entry – Application Design.

Really great post, Thank you for sharing This knowledge. Excellently written article, if only all bloggers offered the same level of content as you, the internet would be a much better place. Please keep it up!!!