An excerpt from my book, Programming Beyond Practices.
Imagine that you work for an agency that helps clients navigate the early stages of product design and project planning.
No matter what problem space you are working in, the first step is always to get ideas out of a client’s head and into the world as quickly as you possibly can. Conversations and wireframes can be useful for finding a starting point, but exploratory programming soon follows because words and pictures alone can only take you so far.
By getting working software into the mix early in the process, product design becomes an interactive collaboration. Fast feedback loops allow stumbling blocks to be quickly identified and dealt with before they can burn up too much time and energy in the later (and more expensive) stages of development.
There are many moving parts in even the most simple software systems, so it pays to set them in motion early on to discover how they interact with one another. In some ways every project is different, but in this sense every project is the same.
This week, you will work with your pairing partner Samara to develop a functional prototype of a music video recommendations system. The initial feature set does not need to be perfectly polished; it just needs to be useful enough to collect feedback from people who may find the product interesting.
Start by understanding the needs behind the project
This music recommendations project is brand new, so you don’t know at all what to expect yet. You get together with the client (Ross) for a quick chat to kick things off:
You: Hi Ross! Thanks for meeting with me. My pairing partner (Samara) is listening in as well. We’re ready to get started if you are.
Ross: Yep, I’m ready. What’s the first step?
You: Well, first of all, I’d like to hear about what got you interested in music video recommendations. Knowing where an idea came from helps us figure out what to focus on in our prototypes.
Ross: OK, sure. We’ve been running a blog where we post curated lists of music videos for a few years now. We have collaborators who specialize in building lists for many kinds of music, and people usually find our posts through organic search.
Over the years, we’ve shared over 4,000 videos on our site. That’s a massive library of music, but the only way to navigate it right now is one blog post at a time.
We started to think through ideas on how to make our collection easier to explore. After considering some options, we decided that building some sort of recommendations system might be the way to go.
The initial version can be simple, but we’d like to get something in front of a few dozen of our most active community members and blog contributors as soon as we can.
You: Sounds like a great project! Let’s dig in.
With the basic theme sorted out, you talk for a few more minutes with Ross about how to get a rough proof of concept put together. One question that often comes up in projects like this is whether the new work will be a standalone project or will need to integrate into some existing system.
In this case, Ross isn’t entirely sure what he wants. But when you suggest that it might make sense to bring the question up later in order to focus all of the team’s energy on figuring out whether the idea will even work, he agrees.
You talk through ways to make the prototype a bit more approachable to the readers of the music video blog and come up with a simple solution: use the blog itself to find the videos that’ll serve as samples in the prototype. This way, the content within the new recommendations system will be familiar to both Ross and the readers of his blog, and there will be a clear connection between the new application and the original website even if they’re technically operating in two totally separate codebases.
Use wireframes to set expectations about functionality
With a few of the big picture ideas sorted out, you shift your focus back to figuring out how to get started on the first iteration of the project. Wireframe diagrams are usually helpful at this stage, because they allow you to communicate the basic structure of what you’re about to build, while creating a shared understanding of the work to be done—without getting bogged down in implementation details.
Rather than getting into a long discussion about different ways of implementing a recommendations system, you suggest starting with what might be “The Simplest Thing That Could Possibly Work.”
You: For our first attempt at a basic user interface, we might start with a page where the video player is displayed front and center. Underneath the player, there will be a few thumbnail images of recommended videos, which will be selected based on whatever is currently playing. Does that sound alright?
Ross: Sure, seems reasonable. I’ll know better when I see it, though.
You: While we’ve been chatting, Samara has been working on a wireframe sketch that might serve as a good starting point. One second, I’ll upload it…
You: What do you think? We’re trying to keep things as simple as possible to start with.
Ross: That looks fine. It’s similar to how I’ve seen video players work elsewhere on the Web, and that will probably make it easy for our users to understand it.
You: Great! Before we take our conversation any further, Samara and I would like to put together something similar to this sketch as an actual web page. We’re just going to use placeholder images for everything, so this won’t take us long, but it will help us test a few basic assumptions that will inform the rest of our work.
Ross: Sure, if you think that will help, go for it.
You are ready to dig in, but Samara appears to be lost in thought. When you ask her what’s wrong, she explains that an idea for a better interface popped into her mind at the exact moment you asked Ross for feedback on her sketch.
Instead of the original workflow, Samara suggests building a player that would show a single video at a time with “thumbs up” and “thumbs down” buttons to allow viewers to indicate their preferences, and a single big “next video” button that would cause a new recommended video to begin playing immediately. This would be roughly similar to flipping through TV channels, but in a smart system that can guess what you might want to watch next.
This is a great idea, but it wouldn’t be quite as easy to implement. After a brief discussion about the tradeoffs, Samara accepts the idea of trying out the more simple approach first, since it provides a faster path toward putting the project into the hands of the real people that might put it to good use.
Set up a live test system as soon as you start coding
The point of rapid prototyping is to reduce distance between everyone involved in a project: both between developer and client, and between client and customer.
To serve both of these purposes, having a running system that everyone can interact with is essential; it promotes trying things out rather than simply talking about them, and makes it easier to share progress as you go. With this in mind, you begin the usual chores involved in getting a web application up and running on the Internet.
Because you are using a decent application hosting platform, this mostly means setting up a generic “Hello World” page using your favorite web framework, and then pushing the code to a Git repository that detects the toolchain you are using. From there, the platform takes care of installing all the necessary dependencies and starting up a web server automatically.
Although it’s running one of those weird URLs that looks like baby-robot-pants-suit.somehostingprovider.com, the application is live on the Internet within minutes.
At this stage, you have no clue what the production environment will end up looking like for the finished project and you don’t really care. You’re building exploratory features that serve the purpose of getting useful feedback from the client’s target audience, and your code will be thrown away before the finished product ships anyway.
You cut every possible corner when it comes to infrastructure—you don’t even set up a database system right away, because it’s not yet clear whether one will be needed or not. Massive underinvestment is the name of the game here, and you manage to pull it off skillfully.
“Should we bother doing any sort of custom styling for this?” Samara asks.
You pause for a moment and think about it. But then you remember the “You ain’t gonna need it” (YAGNI) principle.
“Nope. If the goal of this prototype was to make some sort of slick demo software for a marketing screencast, we’d want to focus on the looks from the get-go. But in this case, I think that Ross just wants to get this in front of a few of his friends to see what they think of it functionality-wise. On top of that, since this is a simple video playing application, the interface is going to be pretty minimal no matter what.”
Samara seems convinced by your answer, even though you’ve once again chosen the expedient path over the elegant one. But you’ve worked together for long enough where this is just something you’re both used to by now; there have been plenty of times where Samara has kept you from overthinking things, too.
You spend a few minutes wiring up the CSS framework you usually use while Samara pieces together some placeholder images. Once that work is done, you write some simple HTML to align the images in a grid layout with some hardcoded captions.
You spend just a little too long trying to figure out exactly where song titles should be placed and what size they should be. But then you remember two important points: none of those details matter right now, and it’s time to get some lunch!
You deploy the code as-is, and a minute later the page is live on the Web:
It really doesn’t look like anything special, and you start to worry that the client will not understand why you might want to show him something this minimal.
To check your assumptions, you ask Samara what she thinks. She points out that not even the most simple things survive first contact with the customer, and that it would be better to ask for feedback too early than it would be to wait too long.
Feeling reassured, you remind yourself that the real goal of this first iteration is to set up a running system that will allow you to rapidly deploy new changes and kickstart the discovery process. From here on out, the client can directly interact with the software, and that will help you move a lot faster.
You send out a quick message to Ross letting him know that you have something ready for him to review, and you take a short break while waiting for a response.
To continue reading, you can check out Part II here.
But if you loved this excerpt, please buy the full book and/or read it on Safari instead. That’s the best way to let an author know you appreciate their work. 🙂
Thanks for reading!