As a tech lead, one of your responsibilities is to deliver robust software that solves a problem, and to deliver it on time. This post is my attempt to set down some things I think are important if you’re going to do that. Nothing below is my own invention, but I’ve tried to avoid referring to any specific methodologies and to use simple language in the hope that everyone will see some of these ideas from a new angle.
Big questions to answer before you start building anything
What are you building, who for and why?
Write these three things down, ideally on a single card to keep it brief. While you’re working, these answers will empower you to make good decisions about what is most important. This is vital because (spoiler alert!) things are going to go wrong and you are probably going to be replanning some of the work during the project.
How are you going to get the solution to the users?
Mobile app? Website? Desktop software? If more than one, which one first?
Answering this question won’t just inform how you approach the work, it will force you to ask if you really understand what your users need.
Can you do it in the time?
Is there a an immovable deadline? What is it? Why does the deadline exist?
Immovable deadlines might be things like “the software we’re replacing goes out of license in six months” or “the startup only has funding for one year”. In this case, how sure are we that we can hit the deadline? If we are worried we can’t hit it, lets deal with that at the start (preferably by reducing the scope).
In the shorter term, you should be asking what the MVP looks like and how long until we can deliver that? The benefit in making this kind of estimate will be that you will know when you are moving slower than expected. In my experience, it also increases trust between you and the people paying the bills if you can explain the plan to them with some target dates on it.
Sometimes there is no immovable deadline because, for example, the team is engaged in an ongoing product enhancement. In this case the MVP, and perhaps even some longer term planning, are even more important, since they give the team structure it will otherwise lack. Without a plan, there’s a risk everyone may just drift along or becoming sidetracked by interesting problems that aren’t why you are here.
I won’t say too much about how to estimate other than, once again, to name check Dan North’s blink estimation, which I’ve mentioned in other posts. However you do it, don’t spend too much time on it. The value in estimates and planning is in the conversations the team and the business have. Like Eisenhower said, “plans are worthless but planning is everything”.
One more thing: your whole team needs to agree that your timelines are realistic. This needs to happen with the entire team because everyone needs to buy into it. If you exclude anyone in the team from this process then you run the risk of someone in the team being presented with a plan they don’t believe in. Do not underestimate the damage this will do to team morale.
When you start building
Get something “complete” out there
This means getting a usable thing out there. It will probably be far short of your MVP, but it will show to the team and the business what your end-to-end process looks like. You want to make it as fast and automatic as you are comfortable with; continuously deploying your code directly into production just as soon as it’s been pushed if you can do that safely.
Here are some examples of types of development and initial end-to-end goals:
- Simple web app with persistence – a Hello World app comprising a simple web client, a server-side app and a running database, all connected together and deployed to your production environment in a manner as similar as possible to your eventual deployment (which means no hacking DNS or turning off the firewall)
- Microservices app – at least two microservices in production, talking to one another over your preferred medium, including service discovery or an alternative. If it’s UI driven then maybe a Hello World UI too.
- Mobile app – a properly named, versioned, deployed app on at least one device, using an app store, showing Hello World, including a server-side component somewhere if one is needed
- Library – a correctly named, versioned, lib deployed to a CDN or repository somewhere with one method in it that prints “Hello World”
Deliver early and often
After that initial step, you’re working towards your MVP, releasing as often as you can. Once your MVP is reached, pick another state you’d like to get to where there’s a noticeable improvement for users of your software and work towards that.
Delivering early and often has two huge advantages: 1) whoever is paying the bills can see progress for themselves and be able to use the app before the project is completed, and 2) your dev team is iterating, so the will get better and better at releasing software and predicting their performance.
I like to think of the “finished” product as nothing more than a strategic goal and imagine a series of increments that will act as useful stepping stones from here to there. Each stepping stone is its own marketable product. This way we can deliver each stepping stone and measure how successful it is one our way to the strategic goal. For example, an automated image processing app might progress as follows:
First we build…
An image viewer, with loading and displaying capabilities
which we enhance into…
A basic editing tool, with contrast/brightness or some touching up tools
to which we add…
A whizz-bang processing algorithm to turn pics into oil paintings or something
which we allow people to save in…
An image catalogue, with storage and tagging capabilities
which we develop into…
A social space, to allow users to upload, store, edit and share their images
And to which we then add…
Some more whizz bang algorithms
Even this set of stepping stones is useful. Maybe when we talk to people about this plan we will find, for example, that the ability to share the images is far more important to people than the ability to edit them. In that case we can reorder our stepping stones and our development has already been supercharged for very little effort.
When things change
The number of things that can change in the middle of your project are mind boggling. Here’s a list of things I’ve seen change in the middle of building software:
- A team member left – this disrupted the team and meant that timelines changed. We had to rethink what we could still achieve in the time
- A feature was more complicated than we thought – this required a reconsideration of what we were trying to achieve and meant we found an easier interim solution
- Someone else released a similar product – we needed to think about whether our product could compete and replanned based on the existence of the other product
- Money dried up – because we were following an agile approach we were capable of just stopping where we were, but we decided to plan out a few additional months of the most important work, planned with the knowledge that there might not be any more active development for a while
- The domain changed – more than once, the world threw us a curve ball: someone created a new category of stuff we had to deal with, a new set of users appeared (using iPads!), users became fixated on a particular feature, Brexit happened. Depending on the scale of the change we did everything from adding new features to the plan to stopping entirely and starting a fresh plan
- The technology changed – someone began deprecating an important library or framework so suddenly we had to plan to get off that technology.
Three things will help massively with this:
- You’re much better off if you can identify problems early so set up mechanisms to notice the ones that aren’t obvious
- When you see a change coming, communicate with everyone to ensure that nobody inside or outside the team is surprised when it happens
- Make changes to accomodate the new reality. Replan. It’s tempting to plough on with the original plan but if things are that bad it might even be necessary to go back and as what you’re building, who for and why?
Communication inside and outside the team
Delivering software is as much about buy in and communication with the client as it is about hitting deadlines and delivering a good product. Sometimes they need some software to be delivered on time come what may, but often they just don’t want to be surprised. If you’ve promised verson 1.0 in July, it is never acceptable to wait until June to tell the client it’ll be late (or on time but incomplete).
By the same token, only communication inside your team is going to ensure that everyone knows what’s happening and everyone can make good decisions. Thus, on my projects, I think about two different sorts of communication:
Inside the team:
Communication is often messy and the plan changes a lot. We might decide something on Monday but dump it on Wednesday when someone uncovers a new fact. I actively promote that openness to change because it is the thing that will make us most likely to head in the right direction. I’d rather admit my mistake yesterday and do well today than plough on for the sake of my own pride.
Outside the team:
This includes clients, managers and the eventual users. We make an effort to communicate clearly by taking our time before making a statement, so as to minimize confusion and ease decision making on the part of the client. You can’t delay too long but two good rules of thumb are that you want to be sure what you’re telling them is correct and you probably already want to have some options ready for what to do next.
Can I write some software now?
I like writing code so I always do some of that with the rest of the team. I’ll pick up a story just like the rest of the team and pair on it. If we’re mobbing I’ll be elbow deep in code like everyone else. However, you do have other responsibilities and you need to keep your head up for what’s coming along next. My old manager once described what I did in development as “a little rudder, a long way from the rocks”. (I have since read that same phrase in the excellent book, Turn the Ship Around, but I swear Bryan said it first!)