Software Development

While a mountaineer might, only somewhat flippantly, tell you that she climb a mountain because “it’s there”, software is normally developed for a specific, singular purpose …

This article detail the development of the application called “TrainTrack”; a very simple, very focused piece of software written here at Greytower. It is not available to the public, and there’s really no plans to make it so. This is about the process.

The Purpose

The purpose of the software is clear: it will monitor train departure and –track information for the long–distance and InterCity trains in Sweden. It will do so in order to facilitate travelling, avoid the dependency on fixed installations such as display boards and monitors in train stations, and finally avoid mistakes such as heading for the wrong track.

The Requirements

When we know the purpose, we can start dealing with specific requirements. This is not a complex system by any measure, but it does have a few peculiarities.

I’m not a requirement expert, as several colleagues might willing attest to, but I do know a trick or two. My first stop is, without fail, the specification–of–specifications: RFC 2119 “Key words for use in RFCs to Indicate Requirement Levels”

This document define, fairly precisly, the phrases “MUST”, “MUST NOT”, “SHOULD”, “SHOULD NOT” and “MAY”. Some of those same requirement colleagues will hate me for it, so I shan’t insist, but personally it’s a set of definitions I prefer using.

These requirements will, in the final stage, be the starting–point for user acceptance, and so must be nailed down firmly. Another personal preference for the nailing process is to use a mindmapper – specifically I would recommend MindJet’s MindManager which, while costly, is probably the best of the bunch*. It’s easy to use and support inclusive modelling by coming very close to human brainstorming.

Let’s split the purpose into more manageable piece:

Monitor train departure and –track information

Facilitate travelling

Avoid fixed installation dependency

Avoid track and scheduling mistakes

This can be rewritten as brief, high–level user stories:

R1: “I must know which departure I can make”

R2: “I need to know if something changes”

R3: “I must have updates while I am travelling to the station”

The above outline the “what” of the project. During the various design phases, we’ll work out the “how”.

Analysis

Before we get too far into the meat of the thing, let’s ask “Does something useful already exists”?

The short answer: no. Several *tools* exists, but none of them are useful in this context.

Fist, SJ’s (local train company) website into which you can add a train ID and glean whether it is in route. You won’t get any estimate on which departure is within reach, and it works poorly — to put it mildly — on anything but a desktop browser. Breaks two requirements.

The accompanying smartphone app requires a login (!) to see when a train is due and, again, no estimates, no alerts. Breaks one requirement.

Design (System/Architecture)

During this phase we’ll try to determine how — in overall terms — to solve the “what”. The result (our output, what we hand over to the next step in the chain) can be referred to as “technical” requirements — and one technique is to turn the user stories above into statements:

R2A2: “To achieve R2 we’ll need to keep retrieving information for a time period bound by arrival time”

And so forth. Based on these results, we’ll decide on a rough architecture:

The application must be web–based. Most mobile devices, if not all, these days have reasonably competent browsers

A web–based application is easily, and efficiently, made using Apache mod_perl

Perl is a good choice for the programming language, as it has a multitude of good libraries and classes supporting web development

The web–part should be contructed using the latest standard, HTML 4.01 + CSS 2.1. HTML 5 is a moving target, and designed by the industry. It offers nothing of value

The design should be tailored towards mobile devices. We’ll use CSS for this purpose

We need no databases, but will place a number of constants in a configuration file. We’ll use Greytower::Config for this

We’ll use Trafikverket’s open API. It’s currently the best one available

We’ll have two exceptions to the standards: refresh and mobile adaptation

We’ll avoid server push, as that complicate the application and offer nothing of value

Principles: * If a value used in a program change often, and because of external events, make it configurable

Design (Details)

Design (Layout)

Creating a functional layout, regardless of the purpose of the software, is a tricky endeavour — not only from the point of view of a developer/programmer, but in general. Experience suggest that even people with design expertise falter.

When it comes to software development, it has been suggested [Crispin; Gregory; 2009] that testers could use the “Wizard of Oz” — or “Paper prototyping” — methodology to test a layout prior to development start:

Developing user interfaces test–first can seem like an intimidating effort. The Wizard of Oz technique can be done before writing a single line of code. The team can test user interaction with the system, and gather plenty of information to understand the desired system behavior. </blockquote>

This is an apt description, but not of the test process, but rather the design and development part of the timeline. Keep in mind that a test will verify “Given X, then Y”, not “Do you like Y?” or “Is Y a good way to achieve X?”.

We will rather start with the requirements. From these, and the analysis done in the steps following, we can determine the elements that need be present:

E1: A field for entering a train ID

E2: A drop–down with possible departure times.

E3: Following E1 + E2 — a button to execute a query in the system

E4: A number of lines of information

E4L1: The name of the station

E4L2: The track on which the train will pass

E4L3: The time the train is announced

E4L4: The *actual* time the train will be there

and so forth. Once the list is complete, a designer would normally be brought in to take these elements, lay them out in an appropriate fashion, take heed of any stylistic guidelines, and go through the process with the end users.

This is also the step in which usability experts would be involved; their work would, in turn, feed back into the technical requirements. For example:

“To search for a specific train manually, the user must input the train ID, then either press CR *or* use a pointing device to activate the ‘search’ button”

or

“The drop–down should contain a list of departures, rendered one time per line in the HH:MM format”

will lead to

S1: The ‘search’ button is a regular HTML ‘submit’ element

S2: The ‘train’ field is a regular HTML ‘input’ element

S3: The drop–down in which to select departures is a HTML ‘select’

S4: The drop–down is population with ‘option’ elements

S5: Each ‘option’ has the train ID as a value and the departure time as a label

S6: The form is only submitted once the ‘submit’ button is pressed

S7: The form is submitted to the mod_perl script in the ‘possibleTimes’ variable.

S8: The drop–down values come from the configuration file

Again: and so forth.

Development (AND test)

First, an oddity. As you may have seen, proponents of an agile methodology suggest that

But developers have by necessity worked like this for many years:

Create functionality; e.g. write a piece of code, a full function or method, or just part of one.

Test it, including building automated tests if possible

Rinse and repeat

More Test

two ways of “running” or “executing” tests:

to ‘run a test’ means, manual context, performing the test steps and summarise

in automated context, execute script or program that in turn run software

Release

Maintain

Rinse and Repeat

Tools

emacs

Perl

MindJet MindManager

tetropy

References

RFC 2219

1. MUST This word, or the terms “REQUIRED” or “SHALL”, mean that the definition is an absolute requirement of the specification.

2. MUST NOT This phrase, or the phrase “SHALL NOT”, mean that the definition is an absolute prohibition of the specification.

3. SHOULD This word, or the adjective “RECOMMENDED”, mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

4. SHOULD NOT This phrase, or the phrase “NOT RECOMMENDED” mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label.

5. MAY This word, or the adjective “OPTIONAL”, mean that an item is truly optional. One vendor may choose to include the item because a particular marketplace requires it or because the vendor feels that it enhances the product while another vendor may omit the same item. An implementation which does not include a particular option MUST be prepared to interoperate with another implementation which does include the option, though perhaps with reduced functionality. In the same vein an implementation which does include a particular option MUST be prepared to interoperate with another implementation which does not include the option (except, of course, for the feature the option provides.)

Footnotes

* Yes, I know about freemind. It has the same capabilities, but is practically useless due to the user interface. In short, the fonts are all bitmapped, and make reading menus etc. near impossible.