Last week I learned that one of the projects I was working on, which, by the way, is probably the best work I’ve designed and programmed— was going to be deleted and not implemented in the client’s product.
The initial reaction is frustration. We all want our work to be meaningful and to matter. Having your code not reach production means you’ve wasted your time. But, as I’ve learned from countless projects, and one should not fall in love with their own code and solution (“Fall in love with the problem, not your solution”). Sometimes the answer to the problem is not in your code, and other solutions are more appropriate. Whether or not my code is in production, my gain from this project is measured in what I’ve learned and that I’m a better programmer because of it.
Then there’s a sense that the customer might be making a mistake. Putting aside the money paid for my time, I’ve provided a genuinely good and solid solution. It’s not like they are implementing a different alternative — it’s just out of scope for now, and too complicated, so why bother maintaining it.
But if I want to follow the guidelines of Extreme Ownership, This is my failure. I was hired to deliver a solution, and for whatever reason, my solution was not implemented. It’s not because I did a bad job, and it’s not because the world changed, or that an alternative was found. Something fell along the way, and perhaps I could/should have prevented that.
This particular project was different from the regular tasks we usually get handed, as it involved setting up a new server in a different language than the one used until now. The requirement was to implement a new solution, rather than fix or add on to the existing code base. This project was mine to manage all the way — I had full autonomy of work; my timeline was flexible; There was no end-user awaiting this solution. It’s a feature that would add a lot to the product, but it hadn’t been asked for by the users.
From a programmer’s point of view, These projects are the best. But I think that more often than not, projects of this type are unlikely to hit production. Once you go on a side project that is not in focus of the rest of the team, people stop paying attention to you. And then, when you come back with the full solution, people need to spend time and effort trying to catch up with you and see how your code helps them and the product, what is required to integrate, what they need to change on their end, how the users are affected, etc.
What I should have done, was to ensure that my changes are incorporated into the main code every week or two. Small, might-be seamless iterations, each time showing a bit more functionality, and keeping everyone in the loop.
Lessons learned from this incident:
- If you’re starting a project that seems out-of-scope of the general product development — either make it part of the scope, or don’t start. If no one is asking about this feature, you’re working on something irrelevant. Always be relevant.
- Part of the solution design is to dice it to as small-as-possible intervals. This is the basic principle of agile development. When you’re working on external modules it’s easy to loose track of this principle because of the flexible nature of the task in hand. The module itself changes a lot in the process, and those affect the building blocks that you planned in the beginning. Change the building blocks if needed, but continue integrating them into the main product.
- Every building block should have a tangible measurement to which it should be accountable. This is an important rule always, but can be lost when things get complicated. If your code is not accountable for anything, no one is paying attention to it, which means you’re not getting feedback, which means that your work is not relevant.
- When you constantly add small changes to the system, people take much more notice of your work. This is intimidating and exciting at the same time. If you take pride in the work you’re doing, let people know about it. If you’re concerned that you might get negative feedback — it’s much better to receive it on small issues that are easy to fix than rewriting/killing a 3 months project. (From experience, knowing how to handle negative feedback is probably more important that writing the code in the first place).
- A hidden positive outcome that comes with small iterations — it allows for better code. If you’re focusing on a small piece of code, you can pay attention to more details. If you’re constantly adding, people put less pressure on you to get your output, which provides you with the time and space needed to write better code.
- This particular project involved introducing a new language and platform (Python/Django) into a solution that is dominantly based on NodeJS. While I think there were good reasons for choosing Python over Node for this project, one needs to take into account that maintaining code that the team is not familiar with has the risk of being re-written or not implemented. (Personally, I think developers should have the ability to move from one language to another, especially for maintenance, but I realize not everyone shares these standards).
- A thought moving ahead, and not directly related to this story: If we’re constantly adding and changing features in the application, we need a system that can handle these changes. It’s one thing to talk and think about adding code. But we need to give equal time and effort to the scenarios of removing code. A key advantage of agile development, and CI/CD methodology is the ability to react quickly to feedback — positive or negative. How complicated is it to kill a feature that we’re working on, mid way? And after it’s been complete? And what if there are other features that are dependent on this particular module?