A tale of two codebases
It was the best the code would ever be; it was the worst the code would ever be.
Let me share two stories about software development.
In the first story, I was working on a software project. For the purposes of this story, it doesn’t really matter which one: after a while, all software projects have similar characteristics. But let’s pick a project in which I was helping build a new billing system for a utility company. The project started well, with a structured approach to architecture and requirements, and it seemed that we had all the time in the world. But, as the project progressed, the time vanished. The list of requirements got longer, not shorter. Programs returned from the testing team with more bugs, not fewer. We replanned, and rescheduled, and rebaselined, but didn’t find any magic ways to create more time. However, we crunched through, and eventually broke into the clear: with a bit of nifty rescoping, and expectation setting, and agreement that we had to release something, we launched the system. We survived the first few months of teething problems, and the system settled down. It wasn’t what had originally been envisaged, and the code was full of compromises and inefficiencies. But it was running - and when it was running well enough, the project was shut down and we walked away, some of us to start the next cycle all over again.
In the second story I was working on a software product. Let’s pick a product which was providing online investment services to consumers. The product development cycle was rather rocky to start off with. It was the early days of online investing - or online anything - and we weren’t really sure what our customers and stakeholders wanted. The first priority was to get something live: something that would give us feedback about customer needs, and prove our connections to the ecosystem of investment product providers. That first version of the product was marginally functional - an online investment platform that didn’t actually let you invest online. But the next version was a bit better, and the next version was a bit better than that. I did eventually walk away - but that was because I left the company, not because the team was disbanded. As far as I know, there is a version of that product - and the product team
It might seem surprising that, in 2024, we are still talking about projects and products as competing paradigms for the delivery of software. Surely, by now, we have figured out the best way to do things, and are all committed to managing our software as a set of products. However, there are many practices (Agile, DevOps, SRE) which, despite become generally recognised as the best way to do things, are still not universally followed - or even followed by the majority of organisations. I believe that this is because those of us who work with technology still do a bad job of explaining to non-technical people why these practices matter.
We are particularly bad at explaining what software is. If you write code for a living, you tend to think of software as highly mutable, never finished, and subject to continous change: it is a job that is never done. If you have never written code for a living, then it is not unreasonable to think of software as fixed and stable (even as you get continuous updates to the applications running on your laptop and phone). After all, those technology people keep using metaphors from construction: they build systems based on an architecture, ideally using building blocks. If you think that software development is like physical construction, then a project seems like the best way to go about it.
Recommended by LinkedIn
How do we explain the true, mutable nature of software to non-technical people, and persuade them that we have to organise for mutability? Consider those two stories again.
In the project story, at the point of launch, or shortly after, during the warranty period (if your plan contains such a period, this is a warning sign), the code in production is the best it will ever be, even though it contains all of the compromises and inefficiencies created during that last crunch period. The people who wrote the code have gone to other projects. If there is a maintenance team, it has little capacity to do anything other than fix critical bugs. More likely, there will be a series of project teams serially formed and disbanded to do enhancements and upgrades. There is a chance those teams will have sufficient time to do some refactoring; there is a much higher chance that they will have just enough time to squeeze some features into a code base that they barely understand. It’s not their fault, but the most likely outcome is that every subsequent project will make the code base a little bit worse.
In the product story, at the point of first release, the code in production is the worst it will ever be. It contains just enough features and characteristics to be worthy of release, but the people who wrote the code have a long list of improvements that they plan to make. And they have the capacity and organisation to make those improvements.
I think that one way to make the case for products over projects is to keep pointing this difference out to non-technical sponsors and stakeholders. If we organise ourselves into a project, we will work hard, spend money and deliver a result - and that result will get worse over time. If we organise ourselves into product team, we will work hard, spend money and deliver a result - and that result will get better over time. The choice is between something that decays and something that grows: I know which I would pick.
(Views in this article are my own.)
I do like the explantion of the differences, and it does lead to the annual planning and budgeting cycle. Not just the immediate financing of the project , but the ongoing financing of the product. Often it is difficult to get Finance to understand that when you have delivered that 'thing' you can't just walk away and let it run and run. Many of the very expensive failures of old applications have occurred because no-one wants to pay for its upgrading and their is no ROI justification, unless you really get them to understand the risk. The company can always do it next year. Lets equate product to a house. Unless you are renting (Software As a Service) where you need to continue to pay rent and the owner fixes the problem, if its your house/home you need to maintain the home constantly as well as paying running costs. So all those applications, upon which your business depends are either rented or owned. Either way, you have ongoing cost or ongoing maintenances and change.
David Knott Your comparison between project-based and product-based software development is eye-opening! It's inspiring to see how embracing a product mindset can lead to continuous improvement over time. Have you found implementing a product-based approach to be more effective in your own work?
enlightening read, such a clear articulation of how to shift our mindset from decay to growth in software development. The 'project vs. product' debate truly is about setting the stage for growth rather than settling for decay. It's a choice that shapes the future of technology.
Really well articulated - I'm a big fan of long-term product teams over short term projects. The latter can work reasonably well if everyone is seasoned, experienced and works well as a team, but this is rarely the case and even so you've designed a process which inherently undermines and weakens quality and long term maintainability. Similarly long-term product team delivery can still be dysfunctional, but it's much more aligned with building quality into the software, and would be my choice any day.
Insightful as always David. One of the key tools I find that helps (as always, if adopted right) is OKRs. Are your OKRs based budgets and project KPIs, or are they based on Product and outcome driven? If OKRs are set well, it can drive effective rolling planning that has more of product and continuous improvement flavour, rather than a set of fragmented project investments.