I have ran into a few snags while trying to update parts of my code that depended on other peoples’ code. Other people updated the interface of their modules, and I needed to update the way my module interacted with theirs. Being slightly optimistic and feeling a bit of schedule pressure, a simple identifier substitution with an occasional update of data type seemed sufficient for the task without actually employing some refactoring techniques.
I was lucky enough to be able to tighten my development cycle. In particular, I was able to jump into testing very early in the implementation of the module. With the use of an automated test tool such as JUnit, the functionality of a module can be continually tested as the module is being developed. The automated test tool is also useful in ensuring that the expected behavior does not change while performing a refactoring such as modifying entity names within a module.
I acted to apply the changes as quickly as it was known to me that an update needed to be done. This resulted in an instance of a big bang that is often dreaded and warned of in software engineering circles. As Franklin says, “Experience keeps a dear school, but fools will learn in no other.” I have read the lessons that Fowler tries to spread in his book, Refactoring: Improving the Design of Existing Code, but I failed to appreciate how applicable his lessons are to my situation. My development cycle was very tight. I was developing a functional unit, testing it, refining it, and then repeating this cycle for other units. I deviated from this cycle, which served me well, by jumping into making multiple global changes at a time. After all changes were made, the suite of unit tests failed, and a sizable part of the day was lost to chasing faults.
I made the decision that it would probably be better to restart the day, since I usually leave my work each day in a stable and acceptable state to continue on the next day. This time, I took a breather and set up some scaffolding, as is suggested in a majority of the refactorings in Fowler’s book. After some scaffolding was set up, I compiled, tested, and continued. Now, I am able to make changes with less risk in a more controlled and well-tested manner. The scaffold allows the code to be functional, while it is being refactored, even if refactoring spans more than a day. Having unit tests available seems to be the primary factor in making this possible, because verifying consistency in a module’s behavior and detecting unintended effects without such tests is likely to be difficult.