I have a friend who recently took over as Project Lead on a relatively new application at his work. There are some changes in that application that he needs to make. The changes range from the smallest portions of the application to some large architectural changes that need to be addressed. As he has discussed it with others they tend to agree that the changes would be nice, but since they don’t directly meet a Business Requirement or provide new functionality and since the system already works, they will have to wait, “After all, you can’t stop a moving train.”
Software Locomotion
How many times have you heard that phrase when discussing needed changes to an application? (Maybe since your a “Software Engineer” someone assumed that software development is like driving a locomotive.) Now, to be fair, one must consider the return-on-investment for any given change to a system. While this is necessary, we cannot afford to let ourselves settle into a paradigm which views software development as akin to the railway. In that paradigm we set our application on the two iron rails of Fast Delivery and Increased Functionality and throw the throttle wide open hoping that those two tracks will lead our application to increased market share and high profit margins.
However, one must also realize that as software ages, or becomes more “mature”, it also increases in complexity as a result of the continual integration of new functionality. This is almost always accompanied by a degradation of the internal structure of an application. Components that once where well partitioned and had clearly defined responsibilities now become bloated and start taking on responsibilities and unrelated functions like a sinking ship takes on water. All of the sudden a seemingly simple change now takes an unbelievably large amount of effort.
At some point the reality that change must be made to an application becomes undeniable to anyone that takes a moment to evaluate the effort exerted for each incremental improvement. This begs the question of why an application must become so complex before someone says, “Hey, I think we need to refactor this thing.”
Refactoring is a buzz word that is floated frequently in software development circles. Is it really understood though? Chances are that if you get a room full of developers together your going to have a significant number of differing opinions on what constitutes refactoring. Luckily, Martin Fowler has written a great book entitled Refactoring: Improving the Design of Existing Code. Fowler lays out a simple definition of refactoring in the preface.
Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. It is a disciplined way to clean up code that minimizes the chances of introducing bugs.
Even though refactoring is a straight forward concept it is one that many developer have a hard time implementing. I honestly believe that it has to do with the paradigm that we as developers use in approaching our development. We are often convinced of the “can’t stop a moving train” argument. Well, what we need to do is approach our development and the changing of our application from a totally different mindset.
The Secrets in the Sauce
My wife and I spend a good portion of our television watching on the Food channel. It just so happened that during an interview with one of the many Food Channel stars that they were discussing what makes a good chief. One of the points made was that a good chief is should taste the food being prepared to see if it needs something more. If the chief finds that it does not taste like they think it should then they add the necessary ingredient to change it. They don’t do this just once, they are constantly doing in. Constant tasting and making the necessary changes when needed and not waiting till the food is completely prepared before going in and making a lot of big changes post-facto, that would be absurd. (I personally have this mental picture of a chief, who after baking a bake, realizes they left the salt out so they just grab the salt shaker and add it right on top of the icing.)
I would contend that just like a good chief, we as software developers must view refactoring in the same way that a good chief views taste testing. Refactoring is an intrinsic part of what we do. It’s not something that is left for a maintenance build. It’s not a nice-to-have, but rather every time we open the code to add new features and functionality or fix a bug, we should ask ourselves how we can change the current code so that it improves the internal structure and cleans things up while adding the needed benefits to our end users. Part of the job of a Programmer is to continually be looking for ways to improve or restore the architecture and design of the system. It is incumbent on developers to be active participants in refactoring the system they are developing because that is a natural part of what it means to be a developer.
Tags: architecture, best practices, refactoring