4 ms·
I have the same reaction. Sometimes there's multiple problems that can all be solved at once, and it is like a force multiplier. Often it's from what you could
by gregmac 4y ago
I have the same reaction. Sometimes there's multiple problems that can all be solved at once, and it is like a force multiplier. Often it's from what you could call "outside the box" thinking, where you maybe take a totally different approach.
For example, there's a bug in the login system, again. Ok, we could probably fix it, but this is an old system built by outside contractors (aka "built cheaply, but expensive to maintain"). It's not the first bug, and won't be the last. There's some technical debt in the way it stores unsalted sha1 passwords, password resets work in a way that allows an attacker to effectively lock out accounts and do a DoS. Looking forward we have customers asking about MFA and SSO support that this system just can't do.
"Solve only one problem" philosophy says to just fix the bug. This is a case where replacing the system (whether buy or build) might make more sense. You have to be pragmatic about this of course, because if you can't live with the bug for however long it takes to replace the system, it isn't going to fly.
I'd still advocate some constraint, though: iteration 1 should fix the bug(s) and underlying tech debt, but shouldn't be adding anything new.
Some of the most productive work I do is this style because it's often only a bit more effort. I used "login system" only as an
easy to understand example, it's often more subtle, along the lines of: refactor a class so it has unit tests and fixes 3 other related but low priority bugs at the same time, instead of just patching. Instead of a day, it takes a week, but more value was delivered (other bugs fixed), there's significantly lower chances of bugs in the future (as future dev work happens), and we can reduce or eliminate manual QA on that component. The extra 4 days have saved dozens we'd spend over the next year if we dogmatically stick to "one thing at a time".
- hbrn 4y agoDoing things incrementally almost always feels more expensive. And sometimes it is. But it is always a net positive in the long run. When you're starting those "replace X system" projects, what you're not anticipating is that half of those projects fail: they're either end up taking way longer than planned, or they don't get finished at all because they miss some critical requirements. The bigger the project, the more risky it is. Your login system has two problems: 1. It has a specific bug 2. It has tech debt The issue is that you're using current bugs as a justification to remove tech debt. Because, let me guess, you want to refactor, but you can't sell refactoring to the management. Here's how management might look at your arguments: > password resets work in a way that allows an attacker to effectively lock out accounts and do a DoS Did it actually happen? I worked at a SaaS startup that had over 50K users, it had the same potential problem. It never happened. Side note: some security standards actually require this DoS vector to exist. > Looking forward we have customers asking And how far in the future are we looking? It might be years before it becomes a real problem. You might be absolutely right in your desire replace the login system. Or you might be a perfectionist that's eager to solve problems that don't matter. The great thing about incremental process is that for a relatively small cost those risks go away.
- gregmac 4y ago> When you're starting those "replace X system" projects, what you're not anticipating is that half of those projects fail: they're either end up taking way longer than planned, or they don't get finished at all because they miss some critical requirements. The bigger the project, the more risky it is. Totally agree! However, there are ways to do them successfully. I've done it many times. There's no need to ever get into a position where you miss a critical requirement, let alone having it prevent completion. My favorite method is building replacement systems in parallel, leaving the existing stuff in place. Often there's a good opportunity to do a totally new feature this way first (maybe allowing you to increase your total addressable market), before you start adding existing features from the old system. > Because, let me guess, you want to refactor, but you can't sell refactoring to the management. Ugh. This statement grates at my soul. First, let's deal with "want to refactor". Up front, as a technologist, I'll admit I do sometimes want to refactor bad code/systems/whatever purely because they're bad. However, as a professional, I know I need to justify that work. This brings to the second part, "sell refactoring to the management". This is just not a conversation that I ever have. If I am (or my team is) being slow due to constantly refactoring code, management is going to question what I'm doing and hold me accountable. If we're slow and causing customer complaints because every time we touch code we add more bugs and start a break-fix cycle... management is going to question what I'm doing and hold me accountable. What I do is look for spots where there's a provable return on investment (justification), and simply make that part of the next bug or feature we're working on. If you can take a system/component/whatever that is constantly getting bug fixes, spend slightly longer on the next fix (because you're refactoring) and then have fewer bugs after and/or be able to implement features faster, that's a win. Do it a couple times, and you'll never be questioned about this type of work. The discussion around doing a large-scale replacement is entirely different, and the ways to justify it are using real numbers such as: potential to hit new market; time spent on support; time spent fixing (repeat) bugs; time it takes to implement changes; time spent fixing new bugs anytime someone modifies the system. Just like above, if you can't prove this, you shouldn't be doing it. >> Looking forward we have customers asking > And how far in the future are we looking? It might be years before it becomes a real problem. Let me clarify my sentence: "Looking forward in the backlog, we currently have open customer requests.." I agree with the sentiment I think you're getting at, which is you shouldn't build to unknown future requirements. You'll pretty much always get it wrong. I teach this to juniors with an analogy like: If you build a foundation for a skyscraper before you actually need a skyscraper, what you'll often find is it needs one more underground parking level than you thought and to be rotated by 15° -- so everything you built is not just wrong but is actively blocking you from building what you need. > You might be absolutely right in your desire replace the login system. Or you might be a perfectionist that's eager to solve problems that don't matter. Let me just be clear, because I wasn't originally, that my "login system" was a fictional example. The real examples I have require too much time to explain adequately. > The great thing about incremental process is that for a relatively small cost those risks go away. The point is sometimes a rewrite makes more sense because it solves several problems at once. This is where I take issue with the original article. You hit on the reasons a full out rewrite fails: Not understanding all requirements. Doing a switch without backwards-compatibility. Going months/years without delivering value. At least I think this is where we align again: The key to a successful rewrite is building incrementally, delivering value as quickly as possible.