The Carrying-Cost of Code: Taking Lean Seriously (2011)
michaelfeathers.typepad.com
michaelfeathers.typepad.com
Also, I have some awesome code I wrote over 10 years ago, and I wouldn't dream of deleting it. There's moments where you make a decision on something, and years later you look the code and say "Who wrote this? This is great!" oh wait...
Code as inventory almost goes hand in hand with coders and machines or assembling line workers. I don't think this is a good direction to take.
In my case, if my code causes a bug, I have a very few steps between the person reporting the bug and the complaint getting to me. It feels personal.
Your suggestion seems to imply it's just money, but how do bean counters effect ground level code decisions in an organization?
It's focus is not on constant refactoring but constant rewriting. Turns out easily rewritable code means easily deletable code. I think the major drawback of this approach is it's hard to follow for systems where you don't yet have some kind of intuitive sense of how the low level implementation requirements since you end up leaving those for last.
makes sense. i guess in my limited experience trying to unit test existing code that's a gnarly mess, as you gradually rewrite it to decouple dependencies and isolate accreted responsibilities into single-purpose collaborator objects that can be dependency injected, and generally get rid of as much global mutable state as possible and replace things with genuine functions, you end up with something that's broken into components that can be easily constructed and tested in isolation. i can understand then how it would be easy to delete some of those components. (not saying your approach is exactly the same as what i am describing here).
re: the link
> While code reuse has been commonly promoted as a universal good over most of the history of computer science, it comes at an increased cost of change & replacement. In order to rewrite a bit of code, one must ensure the rewrite will satisfy its contract with all of its callers.
yes, i can totally appreciate this. i've been on projects where not-very-technical management suddenly decides it wants to focus on reducing the amount of code duplication, as that's a goal and metric that can be talked about while only having a superficial understanding of what's actually going on in the codebase. for codebases with swathes of low-quality code and poor automated test coverage, trying to couple everything together unnecessarily for the goal of "code reuse" can turn out to be a nightmare: a lot of previously unrelated components without solid regression test coverage suddenly depend upon some poorly designed bug-ridden common dependency with a broken abstraction that is constantly getting patched by developers who are touching one or more of the leaf systems that depend upon it.
to quote a pithy line from http://quotes.cat-v.org/programming/
> Before software can be reusable it first has to be usable.
As far as I know I was the only one in the org to do this, and, while I thought initially that it was a slightly outrageous metric, I now believe that if every engineer had taken it upon her/himself to do the same, starting just a few years ago, we'd have wound up in a significantly better place business-wise today.
A corollary to this approach is that Choice of Language Matters; all other things being equal, you should use tools and languages that give you the same functionality with less code.
His idea around three month time based decay on code doesn't seem that feasible to me.
Perhaps what we need is a fixed complexity (LOC and other metrics) target where we're not allowed to exceed that unless specific reasons come up.
100% code coverage is probably another thing that might help reduce dead inventory.
We also can measure what code actually gets used in production, and delete anything not being used. Could even automatically delete code based on lack of usage, and even delete the corresponding tests.
In some domains, I've heard of up to half the code being code that handles rare conditions.
More importantly than removing mature code, it seems to me that pieces of code that are in use and haven't changed in a while are good candidates for applying formal methods.
There were even processes that required justifying branches.
Unsurprisingly people just turned to patterns that masked the cyclomatic complexity from the tools.
Within the Lean model, I think it makes more sense to think of code as something that "weighs down" the different stations in the factory, making them less efficient, like unmaintained workstations in a factory that slowly break down. If you have a station in your software factory representing API changes, then whether or not you have a pile of half-completed work waiting for API changes has little to do with how quickly you can make changes to the API - that's determined by how many changes you've made before.
It's much easier to delete code if you're allowed to delete features. And it's much easier to delete features if you have a clear deprecation and EOL policy, an easy way for customers to determine if they're affected, and simple means of migration.