Software projects are complex. Often the goal of an application looks simple, but as time progresses, the participants realise how complex the it actually is. Usually they fail to consider every type of input and the corresponding output. Fringe cases are often ignored and suddenly need to be accounted for. The most overlooked flaw is a lack of communication between the one who wants to use the software and the one who builds it. Requirements are not fully discussed and expectations are not fully set.
Most projects are difficult because they are not started the right way. The project starts in a direction that has already drifted from the desired outcome. It continues to drift until a lot of changes or even a ‘scrap and rewrite’ are needed to bring it back to course at a much later stage. In this post, I would like to discuss the points which should be taken care of so that you start a software project the right way.
1. Identify the most important users
While most software builders dive into the functionality of an application, the real question to be asked first is: who will use the system? At the very least, the person who requires the software built should be able to answer this question very accurately. If the answer to this question is insufficient, then any further move to build a list of requirements is moot. The first step in identifying what the software should do is to clearly know each of the users who will use the software.
Some important questions are: What is the role of the user? What designation will he/she hold at work? How much authority does he have in the organisation and as a result, how much can he do with or without authorisation? How many times per day / week / month / year does he / she use the application? What 20% of the features will he/she use 80% of the time? Which biggest pain point for this user are we trying to solve?
As a real world example, you can clearly see that Microsoft Word is good for authors, whereas Notepad is good for taking quick notes.
2. Identify the most important use cases
‘Use case’ is a jargon for a description of how a user uses one feature in the system. Each feature has one use case. Each use spells out in clear English sentences how a user will use a feature of an application step by step. Technical specifications are left out. Here is a typical use case for logging in with user name and password.
- User starts the application.
- The application prompts the user for the username and password.
- The user feeds the username and the password.
- The application validates the username and the password.
- If the username or password is incorrect, then the application notifies the user and re-prompts.
- The application allows the user to access the other user cases in the application.
Please note how the authentication use case clearly spells out each step in the use case but doesn’t describe the technical implementation. It is too early in the project to decide implementation. E.g. the user is said to ‘start’ the application. We don’t know if the application is started through a URL on a web browser or through an icon on the home screen or through a command to Alexa. The application is said to ‘prompt’ for the username and password. But the ‘prompt’ can be screen with two fields with something to be keyed in via a keyboard. Or it can be a voice recognition service, where the user speaks and the application prompts and acknowledges with announcements.
After identifying the users in step 1, identification and specification of use cases is the next obvious step. Please note that software architectures such as clean architecture are written with the assumption that use cases have been identified.
3. Document everything
Unless everything that has been spoken is written into words, points may be lost. Start documents with pen and paper, since that is the most convenient way to write notes, doodle and draw block diagrams. But all the roughly written content should be formalised into software documentation. This document should be shared with all the participants. Use an online wiki or something like Google Docs or Evernote to store formal documentation.
Ideally, a client (the one who requires the software built and will use it) should be pro-active, point out mistakes and finally sign off the document as valid before any work specified in those documents is started. In case the client doesn’t respond on time, then the project manager should follow up as much as required.
4. Identify and isolate all inputs and outputs in every use case
Inputs and outputs from every use case should be isolated and discussed. The different inputs and outputs can lead to several permutations and combinations that your application logic must address.
Let’s consider our inputs and outputs in the authentication scenario discussed above.
- Inputs: Username and password
- Outputs: An error message if the username or password is incorrect.
This leads to the following 3 combinations of inputs and outputs in the authentication use case. These 3 combinations must be the branches of logic inside the corresponding use case.
- A wrong username leads to an error ‘Invalid credentials’.
- A right username, but wrong password leads to an error ‘Invalid credentials’.
- A right username and a right password does not output any error.
You can see how easy this makes the programmer’s life. They know the exhaustive list of conditions to write code for. You can also see that in point 3, we have not mentioned that the user will be taken to the next use case. We simply mention that no error is shown. Redirection to the next screen is not considered an ‘output’. It is a transition from use case to another.
5. Identify limits and invalid data
Usually inputs come with certain limits, so that an application can function correctly. E.g. in a field which asks for the year of birth, the input should be a valid year, i.e. a four digit number between the 20th and 21st centuries. These limits should be identified so that the tests can be written and the software can be validated from the day you start developing it.
Beyond limits, consider how the application will behave if wrong data or data outside limits is fed. E.g. what if the user inputs a year of birth in the 17th century or from the future? Ideally, the input field itself should cap the input to a valid range, e.g. a date picker which allows only the valid range of dates to be chosen. But this is not possible if using voice input. So at the very least, validation should be set up to verify if the user is entering the right data.
For every input field in every use case, you should document the limits, valid and invalid data. Based on both the valid and invalid data, tests should be written beforehand so that they are ready when the application is released for testing.
6. Identify the next piece of application you will work on
After documenting all use cases and their logic branches, you will be left with a list of software pieces to start with. This is an excellent time to have a meeting with all the participants: the managers, clients, the software team and quality team. Your list should get sorted by priority.
Based on your discussion, you should have a list of modules you should finish as a proof of concept, the very first version that you are ready to test and roll out. Ideally, this module should solve the user’s biggest pain point. This module should be the reason for the software to be planned in the first place. All other modules may be important, but they mean nothing without the module that has been sorted as top priority and gets the green signal first.
Based on the above six steps, your project should be headed towards a direction agreed upon by all the participants. Sure, there will be hiccups and roadblocks along the way. But as long as your project starts in the correct direction and stays its course, it should gain momentum in the days ahead.