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 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.
ProcessThe 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 PlanningEntrance criteria: An idea, a directive, an opportunity, a problem, whatever...
Tool(s): Project Profile Form
It’s difficult to create anything without a basic understanding of the business objectives. During the planning phase, it’s important to identify these objectives at a high-level.
Step#1: Define the business objectives
Example: Provide a mechanism to organize and distribute related news articles to newsletter subscribers via email.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.
Example: Manage Newsletters (user role) - Create Newsletter, Modify Newsletter, Delete NewsletterExit criteria: Completed Project Profile Form
Application UI layout and structureTool(s): Balsamiq Mockups, writemaps.com
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.
Example: FlexWire mockups - newsletters view, issues view, articles view, subscriptions view, categories view, roles view, templates viewNote: 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.
Example: FlexWire wireframeExit criteria: wireframe, mockups
Application design and developmentTool(s): CFEclipse, Flex Builder, Subclipse, MySQL Admin, FlexUnit, MXUnit, Stax.net
Additional Resources: Tour De Flex, Flex Style Explorer, Flex Skins, Flex Language Reference, Cairngorm, Transfer, ColdSpring
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
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)
- SQL in the form of DDL (Data Definition Language) and DML (Data Manipulation Language) required to build and populate the database
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:
Exit criteria: MXML, ActionScript, CSS, CFML, SQL, DDL / DML committed to SVN trunk and copied to an iteration branch; Unit tests and results
Application testingTool(s): FlexMonkey, Selenium-Flex API, Trac
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 deploymentTool(s): Ant, Maven
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:
- Checkout code from the appropriate SVN tag
- Filter out irrelevant files (i.e. SVN core files)
- Run SQL scripts (DDL and/or DML) to create the required database structure and generate seed data
- Copy/Move files to the production server
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.
Where to go from here: Go get a beer...or two