This is an answer to a question asked on a facebook game dev group:
Throughout my software career I was always confronted with discussing program logic (or business rules) with non-technical people (Marketing, Operations, Customer Service). This became even more acute once I started my own software company. The clients were total strangers with varying level of technical prowess, and if we didn’t understand each other I’d waste valuable resources building something they didn’t want.
I don’t know the number of hours, probably over 1,000, spent documenting requests, ideas, and needs (user requirements). I only have one professional certification and it is from Microsoft in Requirements Gathering (total brag!).
Based on this experience, I can whole heartedly say the simplest, cheapest, and fastest way to get down logic, from which a programmer can then start to code, is the humble Use Case.
What’s a Use Case?
A Use Case comes from super-smart-guy Ivar Jacobson, one of the founders of UML (Unified Modelling Language). UML was the unification of several super-smart-guys trying to figure out best practices on how to make software, specifically the documentation that aids thinking. First published in 1992 Use Cases have been in use ever since in software engineering.
Here ends the academic discussion, let’s get practical!
Really, What’s a Use case?
A use case is a step-by-step description of a process, from a start state to a finish state, to achieve one (and only one) goal. The steps are written conversationally (more on this in a moment), so it is easily understood by techies and non-techies.
Because the Use Case is written in natural language, it is cheap, and fast to create or change. Much more so than code (no matter how bad of a writer you are or how good of a programmer you are).
There are many formalized ways on how to write a Use Case but I keep the structure pretty loose: The most important thing is to get it down. It’s chief and only purpose is to communicate, not to score points for formatting!
Example: Take a Smart Phone Picture
Let’s see how a use case is written by examining a common task most everyone is familiar with: taking a photo with your phone.
1. We begin with an actor.
Other terms are user, player, role, etc. The UML term is actor and I like actor because it clearly states the person or process is acting, it is the initiator of this whole thing. Sometimes there are several different actors who have the same goal. Imagine a website like Amazon. A customer wants to see their previous order history, but so does a Customer Service Agent. The actors are different, but the goal is the same. Sometimes it helps to identify all the actors who will use/benefit from this use case.
Actor: Thomas
2. The Actor has a Goal
The only reason the Actor showed up is because they want to achieve something. What is that something? This should be written as concisely as possible as it is the context for the rest of the use case.
Goal: User wants to take a photo.
3. Then we define the start state.
Often this is unnecessary because everyone knows what the start state is, it doesn’t change or matter OR it is so complicated it deserves its own Use Case so as to not to complicate this one. In our example the start state does matter so we define it.
Begin State:Phone is unlocked
4. Interaction steps
This is the meat of the use case. It is written in a conversational style, like how people take turns with dialog lines in a movie or novel. The Actor goes first because use cases are always initiated by an actor. Once the actor has completed their interaction, the system does something in response. Responses can be anything: file writing, database entries, prompts, text, graphics, animation, sounds, video, force feedback, holographic projections. And that’s it. You just write back and forth. I like to use the names “User” and “System”.
User taps camera icon
System displays live camera feed full screen
User taps circle button or presses a physical button on phone, like a volume button.
System records photo
System employs image stabilization filter based on accelerometer
System takes 3 photos, uses clarity algorithm and selects clearest picture
System saves selected photo as JPEG to photo system in public accessible folder
System plays “ca-chow” sound
System flashes screen white for 16ms, then fades back to live feed over 16ms
Notice how the use case ends with the system having the last word. This is pretty much always the case, because if the user does something more, it requires the system to respond in some way.
5. End State
With the main steps of the use case complete, what is the end state? This is potentially optional as well, like the start state, but it helps a lot of different types of people to know concisely exactly what the result of the above steps are. Sometimes use cases are pages long, so it helps to be able to jump to the end and know the exact state.
End State: JPEG photo saved on public file system
Full Example:
Take a Picture
Actor: Thomas
Goal: User wants to take a photo.
Begin State: Phone is unlocked
Story:
User taps camera icon
System displays live camera feed full screen
User taps circle button or presses a physical button on phone, like a volume button.
System records photo
System employs image stabilization filter based on accelerometer
System takes 3 photos, uses clarity algorithm and selects clearest picture
System saves selected photo as JPEG to photo system in public accessible folder
System plays “ca-chow” sound
System flashes screen white for 16ms, then fades back to live feed over 16ms
End State: JPEG photo saved on public file system
Observations
Notice how everything is in plain language. Anyone can understand what is going on here
Notice the sequence of events is very specific: The image stabilization is employed FIRST then the clarity algorithm. If these were reversed, very different results would occur. This is exactly the kind of “gotcha” tricky stuff use cases capture so well and make obvious to everyone.
Notice the 4th step is one response from the user perspective, yet 5 separate tasks occur. This sets off spidey-sense for the programmer getting them thinking about how to tackle the solution. Should it all be done on one thread or 5 separate threads? When delegating this work, could 5 people separately work on those tasks in parallel to speed up development?
Notice the nouns. Every noun is a hint at something that needs to exist and be interacted with. From this simple simple use case, I already see a bunch of potential tasks:
Need a camera icon
Whatever the camera sensor is seeing must be rendered to the screen. This is easier said than done.
Do we have an image stabilization algorithm? If not, can we build one or license one?
Do we have a clarity algorithm? If not, can we build one or license one?
Do we have file system commands for saving to a public verses private folder?
Do we have an awesome “ca-chow” sound? Where can we get one?
Do we have an animation engine for fades? If not, how long to build one?
Notice words like “if” or “or”. These are hints at logic decisions for the coder.
Next Steps
Use cases are written in such a way that they are almost “pseudo code”. There is nothing in the above that says it should be done in JavaScript or C++, yet it can be implemented in both.
After writing the use case I realized I forgot something important. Modern smart phones record the GPS location at the time the photo was taken. This is an important feature and I mistakenly missed it. Now how hard is it to add to the use case? It’s super simple! Because not a line of code is written we’re still just at the words level, we can add another step: 4.3b Photo is embedded with current GPS location.
I didn’t specifically state that the photo date/time is saved with the phones current date/time, but I believe that is kinda obvious (what else would it be?). This is an example of use cases are as granular as you want them to be. Don’t clutter them with unnecessary details or your readers eyes glaze over.
There are many advantages to writing out functionality this way:
Writing in an action/response mindset helps clarify thinking. What at first seems easy or obvious suddenly isn’t and must be thought through
Order, or sequence, of events is very very clear. This helps the coder immensely
Scheduling tasks can be tracked simply by checking off each step of the story.
Use cases are detailed enough to estimate effort (within a range). With very little invested effort, it is possible to see how expensive this user goal/feature will cost in resources.
The use case immediately becomes a Test Case. Test Cases are how QA checks software is working correctly. How do they know it is working correctly if they weren’t in the room when it was dreamed up? By checking each step in the Story and ensuring the system responds correctly. Then finally by checking the end state. This is one reason why you write out the end state concisely at the end: it’s the final check for QA to ensure the whole use case worked.
Questions
What if the use case is really complicated?
In the photo example there are 5 actions the system must do for step 4. What if it was 40? What if it had complex logic, like “Try to save to iCloud, but if it can’t connect, then save it to the public folder.” This is where UML has Activity and Sequence Diagrams for figuring out just those kinds of problems.
There is mention of an on screen button. How do I know where, how big? The button in your head may be very different from the one in my head!
This is where words are not as useful as pictures. In my consulting career I would always accompany a use case with one or more screen mockups. I use Balsamiq Mockups 3 because it is the fastest easiest to use mockup software on the planet. Here are two examples I made with existing assets in just a few minutes: