Wednesday, April 25, 2012

Design Checklist

It is common to start design and implementation work by concentrating on the functional requirements and leave the non-functional requirements for later. While this strategy works for Proof Of Concept (POC) projects; it is risky for anything else.

Below is a list of non-functional requirements that all applications have to address sooner or later. My experience shows that having these requirements defined from the beginning of the project pays off in the long run, even if the new system will not satisfy all these requirements from day one.


Does the business impose special guidelines on design or algorithms? A typical example is the additional physical tiers in financial and data encryption in medical industries. Organizations may have internal policies affecting design, development, and/or deployment of the applications.


How much of the system can be tested? Affects how the team will need to approach automated testing, code coverage/quality metrics, and design principles (e.g., Dependency Injection (DI)). Most people will agree that automated tests are a must. Designing loosely coupled, easily unit testable components with a DI framework gluing them together, however, is a challenging task that a team may need to schedule time for.


How fast does the system need to process data? Pretty easy to define. Much harder to allocate resources (people, time, infrastructure) and keep consistent measurements (same environment, same data, same processes) early in the project. Unfortunately, very often performance optimization efforts start with end user complaints and leave the "When did it all start?" question unanswered. Getting a baseline of existing performance and comparing performance at planned points throughout the project is often overlooked.


How can the system be built to handle increased load with increased resources? This requirement is related to performance measurements, but implementation is more challenging (even on Azure with API to manage infrastructure.)

Availability (uptime)

How long can the system can be down? One aspect of this requirement is how the system behaves if it loses one of its components (e.g., connection to third party service). Another is how the system will handle maintenance (e.g. upgrades). Normal concerns about shared resource usage/dependability and redundant infrastructure are also in this area.


How fast can the system be recovered? The most commonly assumed aspect is how to recover from failure (e.g., failed DB server recovered from backup). While it is valid, there is at least one more aspect that needs consideration—how to recover from an unsuccessful migration (both broken migration and broken functionality). As you can imagine, upgrading part of the web tier and allowing it to work with an existing database requires certain development approaches and good planning. This requirement will affect the design of the deployment procedures too.

Deployment Flexibility

One of the requirements I've seen a couple times (and that is why I put in a category by itself) is the ability to deploy parts of the system (e.g., web applications) independently of other system parts. Although it sounds easy, it affects design and should be treated seriously from the beginning.

These requirements should help determine values and guide design and coding efforts. Here are some sample questions that suggest some of non-functional requirement are not clear or have not been taken into account:

  • Do we need to write to trace log files?
  • Should I cache user profile data?
  • How can I set up Dependency Injection in my unit test?

No comments:

Post a Comment