Because many software engineers work for bosses who are not themselves programmers, they face the perennial challenge of making the case for refactoring. Perhaps a metaphor will help.
Let the following fraction represent the first version of a program.
Obviously it can, and should, be simplified (refactored)
and indeed, again and again, until it is in lowest terms
In algebra, the simplification is achieved by applying mathematical rules. The purpose of a derivation (or proof) is to stepwise change the form without changing the value. In software engineering, the simplification is achieved by refactoring. The purpose of refactoring is to stepwise change the implementation without changing the behavior. In both fields, the goal is to achieve a form that fosters maximum understanding, clarity and utility. This goal is typically achieved by minimizing the number of symbols (using functions, class hierarchies, and templates, the principle of OnceAndOnlyOnce
, etc.) and/or by conformance to standard representations (DesignPatterns
). In both fields, the simplification steps should be small enough to ensure their correctness. RefactoringTools
can help. In mathematics, training and peer review are used to help insure valid results. In software engineering this assurance is supplied by UnitTests
The first step is to "set up the problem." The canonical teaching aid in mathematics courses is the word problem. Once correctly translated into mathematical notation, the answer is implied by the resulting form, ala equation (1), but is unlikely to be in lowest terms. A mathematician who stopped here would not be regarded as competent.
A first program is like translating a word problem into mathematical notation; it only "sets up the problem" and it is a far more complicated problem. The act of coding is the most effective method for exploring the problem domain and so the resulting first program is heavily influenced by the chance order of events during the encounter of programmer with problem. Because of complexity and chance the first program will be very far from lowest terms - it will need significant refactoring.
If the metaphor were perfect, a programmer who stopped here would be considered incompetent, but because computers are now so darn fast, the first program actually has some utility. In the mists of time, when computers were slow, such programs were in fact regarded as incomplete. They were aggressively refactored, but for speed and to reduce their demands on hardware resources. Today, the goal of refactoring is to maximize MaintainAbility
. Once we have proved a theorem (refactored a program) we want to use the results to prove more difficult theorems (write solutions to harder problems).
We could secure more resources for refactoring if we could demonstrate the business case for it. Being able to solve harder problems is a competitive advantage. Well factored programs, libraries, and classes enable tackling harder problems. Perhaps this analogy will connect with decision makers; future coding is leveraged by well factored code just as reduction to lowest terms leverages mathematical proofs.
Refined version at RefactoringAsReductionToLowestTerms
Refactor = Reduce to the smallest and simplest form that "accurately" represents the original. Is a form of perfection PerfectionIsAchieved
"Perfection is attained not when there is no longer anything to add, but when there is no longer anything to take away...".