Chapter 17

Rapid Development

“God help us; we’re in the hands of engineers.” Dr Ian Malcolm, Jurassic Park

The Startup Genome1 project analysed data from thousands of web start-ups to identify patterns of success, and found a common theme among the 90% that failed. Of these unsuccessful start-ups, 70% had got ahead of themselves and invested effort before it was needed, in what the report calls premature scaling. This can manifest itself in many ways, such as building features that are nice to have but not essential, devoting time to product scalability before the app has evolved to fit the market, and failing to solicit customer feedback regularly.

And so, while code characteristics like maintainability and scalability are important, they are also something of a champagne problem: if they’re your biggest headaches, it’s a good indication that your app has successfully found it’s market.

It’s better to focus early development on immediate concerns to stand the best chance of making it into the small winner’s circle. The Startup Genome project found that problematic start-ups wrote over three times more code than their successful counterparts in the first stage of development2.


For a new app, base your initial technology decisions on:

Before you start development

Your market research and user-tested prototype will form the backbone of your development plan: the list of features that are essential to your customers, how they function, and their user interface behaviour.

Even a minimal app can seem daunting when you first start, so begin by breaking down the features and interface components into discrete tasks. If you’re still clinging on to non-essential features, record these too (so that you don’t forget them) but keep them separate or flag them as lower priority.

img-17_1

Keep track of individual development tasks with a lightweight project management tool like the free Redmine3

If you’re working in a team or with a customer, you need to ensure that there is clarity and consensus on how different aspects of the app are named – the domain language. Does the app record milestones, deadlines, targets or due dates? If it creates a report, what does that mean, exactly?

“There are only two hard things in Computer Science: cache invalidation and naming things.”
Phil Karlton4

Create a shared list of definitions if you need to, but make sure that everyone involved in the project uses the same words to refer to the same concepts. You’ll need to name things in your database, in your code, in the interface and in conversation with technical and non-technical people, so avoid risky misunderstandings and clarify all nomenclature upfront.

Use the platform you know

It’s tempting to learn the hottest new language that you keep reading about, but to get something to test in front of customers as quickly as possible, don’t get caught up in the hype. Use what you already know and enjoy.

If you’re not developing the app in-house but are contracting out the development, stick with proven technologies. The strength of online community is a good signal that a technology is tried and tested. The six most popular web languages – PHP, Java, C#, Perl, Python and Ruby – are all well represented with online discussions and documentation.

The availability of freelancers for a given technology has advantages and drawbacks. As a rule of thumb, contractors of the most popular languages (PHP and Java) are available for the lowest rates, but are slightly less likely to have perfect rating from previous jobs.

img-17_2

Elance5 data shows that the technologies with fewer available contractors tend to have a slightly higher percentage of 5* ratings among those contractors.

img-17_3

Generally speaking, the more contractors that are available for a language, the greater proportion who offer a low rate.

Borrow before you build

To develop an app quickly and easily, it makes sense to write as little code as possible. After non-essential features have been cut or postponed, the next best way of speeding up development is to take advantage of appropriate code that others have written and shared, in the form of libraries, frameworks and web services.

A library is essentially a collection of functions for a given topic. These come in all shapes and sizes, from database connection management and encryption, to image manipulation and Twitter integration. Your code calls a library function, it performs the requested operation, and returns the result and control back to your code. You can choose which parts of a library to use and which parts to ignore; if you only use a single feature of a larger library, that’s perfectly acceptable.

A framework defines a skeleton system, a predetermined flow of calls and fundamental behaviours that you insert business logic into. Because of this loss of control6 over the architecture, it’s a larger commitment to adopt a framework than a library, but you benefit from tested design decisions and prebuilt workflows. If you’re contracting out development, using a framework also gives you some instantly agreed and documented conventions.

A web service (or web API) is the equivalent of a remote library, a set of autonomous functions located on a third-party web server that can be called independently. Web services are often made available instead of libraries when the functionality requires a large repository of data that would be impractical to ship with a library, or access to other centralised resources or data. Examples of web services include the OpenCalais API7 that extracts names, facts and events from unstructured text, and the Google Prediction API8 that provides machine learning capabilities.

Risk increases as you move from libraries to frameworks to web services. Using a library has minimal risk, as you have a copy of the code on your server and you rely on library functions only for discrete tasks. It is usually straightforward to replace one library with another, partially or fully. In contrast, for a framework, much of your code is written to slot into a predefined architecture, which ties the development to the choice of framework more tightly than for a library.

And though you only rely on web services for isolated tasks, the complete lack of control makes them the riskiest form of code reuse: you can’t control the response speed, service uptime, changes to functionality or modifications to the terms of service.

Even so, an established framework will probably expedite the development process and if a suitable web service is available, use it. At this stage, speed and ease of development is vital. You can worry about replacing web services with custom-built local code once the app has successfully evolved to fit the market.

Borrow, maybe beg, but don’t steal. Always check the software licence attached to any library or framework you use. Many will be available under a permissive open source license (such as MIT9 or BSD10) that doesn’t oblige you to take any special action, but some (like the superb Ext JS11) require the purchase of a commercial licence for use in a commercial product.

Model-View-Controller

Many web frameworks (including Rails12, Django13 and the Zend Framework14) implement a model-view-controller (MVC) architecture. This is designed to separate the presentation (user interface) from the business logic, or domain model. The MVC pattern supports our need to create reusable, easily modifiable code quickly:

Most web frameworks organise MVC code into four component types: the front controller, controllers, views and models.

img-17_4

Structure of MVC components in a web app

The front controller is an addition to the classic three-piece MVC pattern. It centralises and handles common issues associated with a web request, such as caching, session management and basic security checks. The front controller also analyses the incoming HTTP message (typically generated by the user clicking an element in the app interface) and delegates the request to a relevant controller.

The role of the controller is to respond appropriately to the specific request. However, the controller should not contain complex logic, but instead use a relevant model or view, or both, to fulfil the request.

A model encapsulates domain logic and data, and often represents a specific entity in the system, such as a document, user or recipe. The model is designed to be completely ignorant of how it is displayed, but instead exposes methods to manipulate and access the model data. A controller uses the model methods to fulfil the request, which may be to select a specific item or update a value.

Where it is the role of the controller to handle the input, the view manages the output. Once the controller has performed the appropriate action on the model, a view renders the output. If it needs to, it can access the data in the model or other values that have been prepared by the controller.

For example, when a user submits a new recipe in a culinary app, the front controller first inspects the incoming recipe data for security risks and prepares the user session. It routes the request to the RecipeController controller, which in turn passes the incoming form data to the createNewRecipe() action inside the RecipeModel model. Finally, the RecipeCreatedView view is called, which accesses the newly created data in the model to display a summary of the recipe under a boilerplate confirmation message.

For maximum code reuse and testability, all domain logic should be located inside models, and controllers should be as thin as possible, in general no more than a few lines of code that call the necessary models or views.

Design for reuse and replacement

The MVC architecture is a good example of the benefits of thoughtfully organised code. By separating presentation from logic and modularising both, we’re able to quickly and easily change independent parts of the app as the market shapes it towards profitability. Similar principles should be used throughout your code.

Keep related things together in the same class, function, or whatever is suitable for your language of choice. Ideally, every unit of code will serve a single purpose, which means that they should be relatively small.

If several units of code contain similar behaviours, the similarities should be abstracted out into a separate generic unit that the others can use. These generic, reusable units should hide as much of their internal complexity as possible and instead expose relatively few straightforward methods15 to limit their abuse.

To make code that is highly reusable and replaceable, it should be loosely coupled. Each unit should be independent and should function with little knowledge of other units. As the Law of Demeter16 puts it, ‘a component should only talk to its immediate friends’. Use techniques like dependency injection17 and the observer pattern18 to reduce coupling in your code.

Front-end libraries and frameworks

Much like server-side code can make use of prebuilt libraries and frameworks to speed up development, so can front-end HTML, CSS and JavaScript.

The HTML5 Boilerplate19 is a useful starting point for app markup. In the spirit of a library, you can choose to cut or keep as much of the skeleton code as you need, from cross-browser and mobile device support, to the accompanying web server configuration (.htaccess) and search engine (robots.txt) files.

img-17_5

Part of the HTML5 Boilerplate

Most CSS and JavaScript frameworks provide two crucial benefits to development speed. They are designed to neutralise cross-browser discrepancies, and to reduce the amount of code needed by providing shortcuts to complicated features and commonly used techniques.

A reset style sheet is the most basic type of CSS library. It defines a set of rules to remove inconsistent browser default styles, such as the margin around a form. A reset style sheet is purposely liberal to ensure the highest level of consistency, and it can even remove some default styles that are useful, like italic <em> text or headings that are larger than paragraph text. As Eric Meyer says for his Reset CSS20 style sheet, “The reset styles given here are intentionally very generic. […] It should be tweaked, edited, extended, and otherwise tuned to match your specific reset baseline.”

The Yahoo! Base CSS21 file is an extension to their reset file22 that applies a consistent baseline style to common HTML elements. This approach of removing variations and applying a baseline is combined in the normalize.css23 file, which not only sets a consistent default style but also fixes a number of browser rendering bugs.

After browser variations have been neutralised, CSS grid frameworks can help to arrange app interfaces that are designed with a grid layout. The 960 Grid System24 defines a 960 pixels-wide grid with 12 or 16 columns; the 1Kb CSS Grid25 and Yahoo! Grids CSS26 are more configurable in width and number of columns. Blueprint27 goes one step further and combines a grid, reset style sheet and baseline style into a single CSS framework.

Instead of prebuilt classes and styles, extensions to CSS add new features to the core language to make CSS development faster and easier to change. LESS28 and Sass29 offer comparable support for CSS variables, functions and nested rules, with minor differences in syntax. Both systems include server-side compilers to convert their bespoke CSS language into standard CSS files, and both offer a ‘watch’ feature that automatically recreates a standard CSS file whenever a change to the custom LESS or Sass file is detected.

LESS Sass
@main-color: #333333; $main-color: #333333;
.photoframe(@width: 5px) {
border: @width solid #eee;
}
@mixin photoframe($width: 5px) {
border: $width solid #eee;
}
.large-photo {
color: @main-color;
.bordered(10px);
}
.large-photo {
color: $main-color;
@include bordered(10px);
}

Minor differences in syntax between LESS and Sass

Compass30 combines the reset, baseline and grid styles of Blueprint with the features of Sass. There’s also an accompanying cross-platform Compass app31 to help you set up new projects and automatically compile CSS.

When it comes to JavaScript libraries, jQuery32 reigns supreme. As of September 2011, jQuery is used on half of the 10,000 most popular websites, and is steadily growing33. The cross-browser library makes it easy to select and modify DOM elements, manipulate style, respond to events and make Ajax calls. It is also designed to support plug-ins, of which there are thousands34, ranging from form validation to multimedia players.

Other comparable JavaScript libraries tend to focus more on providing advanced object oriented features, so jQuery’s straightforward DOM and style manipulation make it particularly suited to rapid app interface development. The jQuery UI library extends jQuery to introduce practical interactions (drag-and-drop, resize, sort), effects (fade, hide, slide) and widgets (calendar, progress bar, tabs). The library is one of the simplest tools that you can exploit to quickly build a rich web app interface, with the bonus that jQuery UI widgets can be easily styled with themes to match your design.

img-17_6

jQuery UI provides numerous ready-built widgets and themes

Summary

Many developers have a deep-rooted need to solve problems elegantly and they invest time in the minutiae of artful custom code. While this can be a desirable trait for the stability and longevity of established products, the unpredictability of early-stage apps demands a less fastidious mindset.

Web App Success book coverAlso available to buy in a beautiful limited edition paperback and eBook.

This work is licensed under a Creative Commons Attribution 4.0 International License.