My background is in physics and math. I can remember my first advanced mechanics course. The professor was solving a rather innocuous looking problem. The first black board was filled with equations quickly followed by the second, third and fourth. The professor appeared to be a magician waving his wand over the board as technique after incredulous techique flowed from him. Integration by parts followed a deft use of completing the square. On and on it went until forty-five minutes and six black boards later the problem was solved. I was left breathless. Clearly the black arts had their hand in this weaving of advanced mathematics and only artists such as Jackson Pollack could see the beauty in what was created.
Was this a display of art or well practiced skill?
Before we move towards an answer, let’s define succinctly what is meant by art and what is meant by skill. Using Merriam-Webster as a reference, art implies a personal, unanalyzable creative power whereas skill stresses technical knowledge and proficiency.
At the time I witnessed that display of mathematical prowess, given my limited experiences, I will admit that I believed I was watching an art. There was simply no way for me to imagine that the succession of techniques coupled with a vision of the desired solution could be known a priori.
While taking the mechanics course I was also taking differential equations and another advanced mathematics course. Over the period of the three courses I began to see that there was no man behind a curtain controlling a mystical presence. Practicing technique after technique hundreds of times in different progressions slowly built up a type of vision. Initially I could not see step B from step A unless I was told the technique to use and actually worked through to the result. Eventually, I was able to see step B without being told which technique to use. I then progressed to seeing step C and D from A without ever writing down a single equation. Directly from step A I was able to see if applying one technique would lead me to a dead end three or four steps ahead. Through the systematic practice of techniques I was able to develop a skill.
Had I taken the mathematical courses before the mechanics course, I would have never believed that I was seeing an art. It was necessary for me to first build up a skill before I could comprehend what was going on (thereby ingraining the meaning of the word prerequisite indelibly into my brain).
Software refactoring is a relatively new technique. One could argue that it has only been recently with the introduction of appropriate tools (i.e. IDE’s with refactoring support) that refactoring could be effectively practiced. With such a short existence, it is no wonder that refactoring appears more like an art than the systematic practice (a skill) that it actually is. What’s more is that most software engineers do not have the knowlegde of the desired end result.
Let us contrast this with the mechanics story from above. Most academic mechanics problems are stated in the following way:
Determine the equations of motion for X to move along surface defined by Y under the influence of force Z.
“equations of motion” have a succinctly defined form — you know exactly what the form of the results should look like. One simply has to take the givens and manipulate them until they are in the desired form. But what is the desired form in software engineering?
Using quality as a basis, it is clear to me what the desired end result of refactoring looks like. Unfortunately, it is not a simple expression as in mechanics. It is a careful weighting of many factors including coupling, clarity, size and so on. To compound the problem even further, each factor is not well defined. What is “clarity”? How is “coupling” measured? What is good coupling and what is bad? None of these questions have a single answer and attempting to find the composite of these multivalued solutions may just be NP-hard.
Is there a solution to this refactoring problem? I believe that there is. But before we can begin looking for solutions, we need to better understand and define the problems. Once we finally make the jump from:
Refactoring is an art
Refactoring is a skill that requires much practice and experience with maintaining the end result
then we can begin to find objective means from which solutions are derived.
At the core I believe that this is a training issue. Whereas I spent years manipulating equations so that I could see the results before ever writing a single equation, CS students do not spend years writing and maintaining code. Unless you have spent considerable time understanding and working with the implications of various results how can you being to refactor code?