I’ve been delivering software since 2005, and have served in various roles: starting as a software developer, then leading teams of software engineers and recently running a company I co-founded. When starting PINKDROIDS and building our software delivery process, I’ve tried to incorporate what I knew worked, while being mindful of the company culture that we wanted to build.
Our process is still evolving, and will likely continue to evolve indefinitely. Still, it seems to be working pretty well, and this prompted me to write an article about what I consider to be key factors when it comes to a software project being successful.
This article from the Project Management Institute (PMI) lists the following top contributing factors to project success:
Clear business objectives
According to this study conducted by PMI, 39% of all failed projects fail due to bad requirements and 28% due to inaccurate cost estimates.
This is in line with my experience working on software projects, but I want to expand on this theory with a practical list of key steps that ensure the success of every software project.
Let's kick things off with arguably the most important component of a successful software project; this one is mostly unrelated to programming.
1. Product discovery
At this point in our engagement with the client, we’ve established they have clear business objectives that we are expected to meet. Now it is our job to make sure we have a crisp understanding of these objectives.
What is product discovery?
Product discovery is a process in which the software development company and the client share a number of sessions to establish the common language in the domain being implemented and through which the developers are able to understand the business process that they are tasked with automating.
This process may repeat multiple times in an agile environment, but this initial stage will result with:
One or more documents listing all of the user stories for all of the different roles delivered to the client
A clickable prototype that the client can try out, give feedback on and finally approve.
A proposal with an estimate or a fixed price quote and the implementation timeline
What is its value?
The value of the discovery process is making sure that the correct features will be developed, saving the cost of development for the client as well as the company looking to develop the software.
When should it be done?
Ideally, this process will be done before any programming has started, and the software company will be compensated for the work. After the delivery, the client can choose to accept the vendor’s proposal or use it to request quotes from additional vendors.
In reality, as a small/young company trying to get early clients we’ve had to deal with both of the following scenarios:
Having to provide a quote without proper discovery and hope to be able to minimize our losses
Offer to do discovery for free so that we may come up with a higher quality estimate and be compensated for our time if we land the project
Neither of the two are ideal, although I could tell a few compelling stories where going each of those routes paid off resulting with some of our best clients to date.
I am confident though, that if we didn’t start the discovery process right at the very start, we would not only lose money in the first phases of development, but would probably lose the clients for implementing the wrong features.
Product discovery is an invaluable part of the software development process and should (almost) never be skipped, as it provides the software company with knowledge that is absolutely necessary to make a quality estimate. Acceptable exceptions may be very simple projects or projects where the business domain is clearly known.
As a final thought, a little bit of discovery is better than no discovery. If a lead you are interested to work with is not willing or able to pay for discovery, you should always be able to at least get them on the phone a few times to talk about the project before you commit to a quote. The hotter the lead, the more time you should be willing to invest.
2. Client engagement
The client should be routinely included in the process of developing their product on some level. Depending on the size of the client company, this can either be the company owner, product owner or a project manager.
When it comes to mitigating the risk of developing the wrong features and developing features wrong, communicating with the right people in the clients’ organization is king.
Communication with the client should be direct, honest and transparent. No sweeping things under the carpet. If it feels like a painful conversation, strive to bring that pain forward.
Honesty is almost always appreciated; direct and transparent communication is what our clients regularly emphasize when reviewing our work.
When working with larger organizations, I’ve often found that one or more champions of the project will surface in the lower levels of the organization. This will be someone who has an operational stake in the project; someone who will experience direct benefit from the project when it comes to performing their duties. It has always served us and the project well to embrace this person and promote their enthusiasm to their superiors.
Mind the red flags
In contrast, the following red flags should be looked for actively:
The client is unresponsive to project queries in early stages of product discovery
Can’t get the client to provide feedback on delivered sprints after the software development has started
As software developers, it is our job to do whatever we can to correct these problems quickly, but if fixing the problem becomes impossible, a decision should be made against accepting the project in the former or gently dropping the client in the latter case.
It is unpleasant, but failing to do so is setting oneself for failure. The project will have a hard time succeeding without support from the client.
3. Fast iterations and short feedback loops
The first thing we do when starting software development work on a new project is configure the project for automated build and deployment to a staging environment. This serves four purposes:
It establishes a project wide expectation that each feature checked into the code repository is 100% complete, as it will be visible to all stakeholders of the project.
Giving the client early and continuous access to the product allows for their feedback early in the development process, lowering the risk of implementing the wrong features.
Automated builds are accompanied by automated code quality checks. Doing so will result in better code; as opposed to having to fix a bunch of bad code that would pile up in the course of the project if quality checks were not present.
Helps to identify communication red flags early
An additional benefit of doing this is that it is much easier to track the progress of the project. If each feature is 100% complete and verified by a client as it is checked in and deployed to staging, then project planning becomes measurable and actionable:
The development company can compare the project plan to project results accurately and escalate if the project is late either by adding more developers, cutting requirements or asking for a delay in deadlines early instead of doing it on the last week of the project
Based on previous sprint feedback the developers can estimate the number of hours that will be spent in the next sprint addressing client feedback
4. A communication centric development process
Individual skill counts (a sidenote)
At the root of any development team is the programmer writing the code. In my view, a programmer's ability is determined by their experience, discipline/work ethic and their problem solving and communication skills. I think it goes without saying that hiring good senior as well as junior programmers is paramount to building a good development team.
Back to the process
Beyond individual abilities of each team member is the process of implementing features by way of writing code.
Agile processes are widely accepted in software development today. There are many methodologies that offer “implementations” of the agile process. Some of them offer new innovative ways to be agile, and many of them just rehash the same old thing.
Reading up and learning about them seems to be the correct way, taking the things that fit the culture of the team the company and incorporating them into the process. Then keep iterating by tweaking each part of the process continually, keeping what works, fixing what doesn’t, and throwing away the unfixable.
Our process (a part of it)
There are a lot of moving parts to our process, and the process is constantly evolving. Detailing our process of writing code and how it evolved to the state it is in now could be an article in itself, and most likely will be in the future.
For this article, I want to concentrate on three communication centered guidelines for developing code that have improved our deliveries both in quality and timeline to a larger degree than we expected.
Master branch is the production branch
Peer code reviews
Standardized commit messages
Master branch is the production branch
This is mostly a matter of psychology. There are alternative schools that propose the use of a production branch separate from a master branch, but in my experience this comes with an unnecessary set of problems. Having a single source of truth, which in this case states that whatever is in the master branch is ready for production, streamlines the definition of done. If it’s less than 100% done, it should live in a separate branch, clearly communicating to all that it is not done.
Peer code reviews
Senior developers should review junior developers' code. It is a valuable teaching opportunity, but also more than that. The psychological component is clear; if someone will review the work I have done, I am less likely to opt to shortcuts and quick fixes that might be hurtful in the long run.
The vice versa applies as well. Junior developers should review senior developer code both for learning opportunities and to reduce the chance of seniors to take shortcuts in crunch times.
Company culture is important here. Reviews should be honest, direct and respectful. Anyone’s code is fair game, attacking the person behind the code is not.
Standardized commit messages
I’m not really sure if there is a measurable benefit to this. However, a few years back we started to standardize our commit messages. Every message must be in an imperative mood, following a strict restriction of length for the main line and separation of the following lines. There’s more, and it’s pretty well described here.
There is an aesthetic benefit to this, in the sense that looking at the commit log looks tidy and every commit message states clearly what change is that commit introducing to the code base.
But, more than that, it communicates to the entire team that the code base being developed is carefully nurtured. No broken windows here.
Of course, having clean, simple, well tested code is the basis, and even though projects with a bad code base can be successful initially, the technical debt introduced by bad code will come back to bite the culprit sooner or later.
While this list is by no means a definitive guide to project success, I do feel it’s an accurate high level description of my account on what the biggest drivers of success in software development are.