The analogy works in another way as well, not only with respect to the consequences of debt, but also with respect to its root cause - i.e. why we go into debt in the first place. This side of the equation, however, is seldom examined. Most often we naively suggest the problem lies with discipline or motivation, and the solution is just to try harder...but usually to no avail.
To truly understand why we go into debt, however, I believe we must first understand the individual decisions we make as consumers (when we spend or save) or as developers (when refactor or keep coding) - to boil the decision down to its basic elements: the beliefs, thoughts, and information that leads us to save or to refactor. When we do so, I think it becomes very clear why developers actually often do not refactor or clean up their code – a decision theorist might even say it's not rational do so. Developers are merely weighing present costs and rewards versus future ones, and in the chaotic and transient world of software development, the benefits of hitting immediate release dates far outweigh the costs of maintenance (most likely for some other poor soul!) in the future.
Code quality tools like PMD, PMDReports, and Checkstyle rebalance this equation, however, by affecting the individual costs and benefits that go into the decision to refactor or not. From this perspective, it is clear that in any development organization, they are a crucial precursor to keeping code clean and staying out of code debt.
Decision Theory and Refactoring
Decision Theory tells us that people inherently prefer present rewards to future ones - "eat, drink, and be merry, for tomorrow we'll die". I could spend my money and enjoy it now, or I can put it away and hope that with interest I'll live to enjoy a little more of it later.
This exact dilemma of now-versus-later is also hidden within a developer's decision to refactor. He can either enjoy all the benefits associated with 1 free hour now (gained by not refactoring), or he can spend that hour on refactoring his code and thus lower his chances for pain in the future (in the form of bug fixes or maintenance frustrations). In the terms of decision theory, he's balancing present costs and rewards with those in the future, and when examined in this way, it's more clear why he doesn't refactor in some cases.
To understand this refactor-or-not-refactor decision, we need to look at its component costs and benefits:
A (cost): the certain cost of refactoring
B (benefit): the chance of reaping some quality and maintainability rewards in the future C (benefit): the chance of gaining a good reputation from writing solid code. |
The subjective beliefs a developer has on a number of seemingly extraneous things can all affect the values he gives to each of A, B, and C. For example, if he doesn't expect to be at a company long, then he may devalue the future rewards of quality and maintainability in B and perhaps the reputation gains in C as well. Or if a developer expects the chance of a system being scrapped soon is high, then similarly his expectation of the benefits of B are diminished. The point is that what seems like a simple decision, is actually a fairly complex one containing dimensions of uncertainty, intertemporal preference.
Code Quality Tools to the Rescue
Here's where code quality tools come in. PMD, Checkstyle, and the like fundamentally change the basic variables in this refactoring equation. Here's how:
1) Reducing Cost (A): Code quality tools tell you exactly what the problem is and in many cases how to remedy it. Knowledge of what to do significantly reduces the time to actually do it.
2) Reputation via Visibility (C): Before the advent of code quality tools, Beck and Fowler tell us that we must rely on our sense of smell (that is “code smell") to discover problems in quality. This of course is limiting, for what we do not see we cannot smell. In most environments, code is never truly inspected by anyone but the writer himself, and so the quality of the code is never known. PMD and Checkstyle change this. Both provide objective and accurate measures of code via simple mechanism (i.e. an Eclipse plugin or build-driven report), making it quite easy to discern whether a developer is churning out good code or crappy code. As developers, we know that our reputation is what keeps us employed – so if everyone knows what kind of code we're writing, then our reputation depends on the quality of our code (and not how well we speak in meetings!). 3) Inspection without Social Tension (A): Also related to reputation, reviewers of code are often loathe to point out pedantic nit-picks in code and risk a hit to their own reputation (no one wants to be the guy who complains about brackets and spaces). With code quality tools, the tool will point out the code peccadillo so you don't have to. This saves the reviewer time and frustration. In the end, this can be considered a reduction in the cost of refactoring. 4) Satisfaction: I also believe that code quality tools like PMD and Checkstyle introduce a new variable in the equation, I'll call it (D): the satisfaction of fixing a violation. Though this may be spurious (as it is more of a perceived benefit more than actual), it's very effective. I often find myself a bit obsessive about fixing violations so I don't see that yellow flag in my Eclipse editor next to the infraction. In some way this seems to be a non-trivial “reward" realized in the present that developers receive from refactoring. |
The point of this all extends further than just code quality tools, though. We as developers are really just decision makers. Each line of code we write is really a decision in its own right, and these decisions are the product of our personalities, environment, culture, education, and beliefs. Too often we focus on the on the code itself, and fail to look upstream at its precursor: the decision.