This is an inoffical new feature request – I am floating between sarkasm and really considering to implement this.
Here it is, I proudly present:
The [Rotten] attribute*
* Other candidate names are: [Smells], [CodeSmell], [Stinks]
The principle is simple:
- If you find a piece of code that is of very low quality, annotate it with the [Rotten] attribute.
- The tooling (e.g., Resharper, CI, any quality management tools such as SonarCube) does the rest for you:
- The properties, methods, or classes (short: code unit) marked with the attribute are considered “rotten” and are marked as such – this could be anything ranging from a simple Resharper warning to a “rotten lines quotient” or the like, to gamification tools such as the Jenkins game plugin which would punish the introduction of and reward the removal of rotten code (though introduction of the attribute and the cascading markings should not count).
- Any code unit that directly depends on a rotten code unit is itself considered rotten.
- Any code unit that directly inherits from rotten code is itself considered rotten, too.
- These rules are applied recursively such as to propagate the rot to the uttermost thing depending on the rotten cluster of code.
Help – my code is marked “rotten” – what can I do?
You can take the following measures to bring down your “rotten code quotient”:
1. Fix the rotten code.
Cover it with unit tests, refactor it, fix the bugs, remove the smell, make it readable. Once you are finished, remove the attribute – all of your dependent code will immediately get rid of its “rotten” status, too.
2. If 1. is not (yet) possible: Protect yourself against the rotten code
Remove direct dependencies on rotten units. For “has-a” dependencies: Invert your dependency. Put a well-defined interface between the two units. Then you can cover both sides with unit tests to document the behavior of the rotten unit, including correct and incorrect parts, and verify that your “clean” unit handles both correct and incorrect parts properly. It will also loosen the coupling of your not-in-itself-rotten code to the rotten part. It will improve odds that you will ever be able to simply exchange the rotten unit by a newly-written one.
In severe cases you could even consider to introduce a mediator class/adapter class between rotten and clean units. They could “even the bumps” and prevent the clean part from assimilating to the rotten part.
For “is-a” dependencies (i.e., subclasses) – Stop inheriting from that rotten base class. Introduce an interface for other code pieces so you can satisfy them without inheriting from a base class. Introduce a new clean baseclass, or stop subclassing at all – it might be part of the problem that led to the code rot.
3. Are you kidding?
Kind of. Only. If you take the measures above, you will manage to keep as much as possible of your code secure from being infected by the rot of the already-rotten parts. If you do not take these measures, and the code that you might consider clean depends on rotten code, your clean code will misbehave and become hard to maintain just as the rotten code does, because code rot is infectious. This is why this code is harshly considered “rotten”, too, thus providing an incentive to fix that.