I feel that most 100K line programs could be rewritten with just 10K lines and end up being more reliable. Feature creep is responsible for some of the code bloat but I can guarantee from experience that, in the vast majority of projects, you could keep all the features and still cut the code to at least 1/10th of its size. I think the reason for this is because developers who focus on development speed do so at the…
May I venture that you're probably early in your career? There's almost always things that can be redesigned to be better and smaller if one has a better understanding of total scope from the beginning, but there's equally as much discovery that the reason things seemed unnecessarily complicated was a lack of understanding of the complexity, and that the new rewrite eventually reintroduces much of it as it's used in…
1. With each feature request, pick one thing to improve (a bug, tests testing mocks instead of code, duplicate classes, inconsistent error handling strategies, complicated logic, ....).
2. First make the improvement. Propagate the beneficial impacts throughout the codebase (remove methods that only existed to support the mock, remove utility methods that only existed to support those, remove tests for the utility methods, remove duplicate tests on the previously duplicated classes, remove code duplication elsewhere that bifurcated due to the duplicated classes, change your Result return type to just a T type because your sanity check was wrong and the method can't actually fail, you no longer need to pattern match (or catch exceptions) on that result type because failure isn't an option, ....).
3. Then implement the feature. The nearby code was just improved, so this is a bit easier than it would have been.
4. Repeat ad infinitum.
After doing this consistently for a little while, the 10x reduction in code happens on its own, and it's faster to implement new features _and_ fix the little bugaboos than it was to just implement a feature starting out. Your code is more stable, your builds are faster, your code is faster, your tests are faster, your tests catch real bugs, feature velocity goes up, you don't accidentally expose a race condition in your driver because of dumb concurrent complexity in the application, and on and on.
Then, if an architectural mismatch exists, the code is in an understandable state. It's leaps and bounds easier to re-write a 10k project than a 100k project.
YMMV. Not all code is that bad, but a significant fraction of older projects turn out that way eventually.