{"id":263,"date":"2014-11-28T08:10:50","date_gmt":"2014-11-28T08:10:50","guid":{"rendered":"http:\/\/localhost:8000\/?p=263"},"modified":"2025-09-07T13:47:22","modified_gmt":"2025-09-07T13:47:22","slug":"some-thoughts-on-refactoring","status":"publish","type":"post","link":"https:\/\/blog.gwadej.org\/programmer-musings\/2014\/11\/some-thoughts-on-refactoring\/","title":{"rendered":"Some Thoughts on Refactoring"},"content":{"rendered":"<p>I recently heard an <a href=\"http:\/\/devchat.tv\/ruby-rogues\/178-rr-book-club-refactoring-ruby-with-martin-fowler\">interview<\/a> with <a href=\"http:\/\/martinfowler.com\/\">Martin Fowler<\/a> on the <a href=\"http:\/\/devchat.tv\/ruby-rogues\">Ruby Rogues podcast<\/a>. He pointed out a few things about the process of refactoring that I haven&#8217;t thought of in a while. Based on that interview and what I&#8217;ve read and learned elsewhere about refactoring in the past few years, I decided there are a few points worth making:<\/p>\n<h2 class=\"subhead\">Don&#8217;t Change External Behavior<\/h2>\n<p>By definition, refactoring improves the design of the code without changing externally observable behavior. If you change the behavior, it&#8217;s not a refactor. It&#8217;s a bug fix, or a restructure, or a redesign, or a re-architecture. Too many people use the term refactor to mean &#8220;I futzed around in the code for a while, but didn&#8217;t fix any bugs or implement any features.&#8221; That is not the same thing as refactoring.<\/p>\n<p>When you decide some code needs to be refactored, remember that you don&#8217;t want anything outside the code you are changing to be able to see any difference. This is part of the reason why unit tests are so important to refactoring. Without good unit tests, how are you going to know if anything has changed?<\/p>\n<h2 class=\"subhead\">Most Refactoring is Small<\/h2>\n<p>In the interview above, Martin Fowler explicitly stated that small refactorings are good. If you look at the definitions in the Refactoring book, you&#8217;ll notice how small each change really is. You might wonder how any change could make a difference. Experience among a large number of programmers has shown that small changes can incrementally improve the code. It&#8217;s slower than a <em>big bang<\/em> rewrite, but it&#8217;s also much safer. Since each change is small, the risk of a major failure is also small.<\/p>\n<p>Another advantage of small refactoring that many don&#8217;t notice is that each <em>successful<\/em> refactor improves your understanding of the code. More understanding leads to better changes. It&#8217;s reasonable to suppose that a series of changes based on increasing knowledge can result in better code.<\/p>\n<h2 class=\"subhead\">When a Refactor Breaks<\/h2>\n<p>In the same interview, Martin Fowler also made a point that I don&#8217;t believe I&#8217;ve ever heard before. If you refactor some code and it breaks the tests, don&#8217;t debug your refactoring. Throw it away, instead.<\/p>\n<p>If your refactoring changes are small, it won&#8217;t cost you much time to throw it away. More importantly, if you throw away the change and try again, the time you spend on the change is well-defined and limited. On the other hand, we all know that debugging can be an unbounded, hard-to-estimate time-sink.<\/p>\n<p>If you broke code with a refactor, that probably means at least one of the following:<\/p>\n<ul>\n<li>You made too big a change in one step<\/li>\n<li>You didn&#8217;t actually understand the code as well as you thought<\/li>\n<li>You didn&#8217;t properly account for side effects of your change<\/li>\n<\/ul>\n<p>If you think about it, the first one of those is obviously best solved by trying again, but aiming for a smaller change. The other two are most likely in the realm of unbounded debugging sessions.<\/p>\n<p>Always make your refactoring changes as small as possible and be prepared to back up if something goes wrong. Good version control helps with this.<\/p>\n<h2 class=\"subhead\">Refactoring and Tools<\/h2>\n<p>Some people will make the argument that an <acronym title=\"Integrated Development Environment\">IDE<\/acronym> with refactoring support is required to actually refactor code. This ignores the fact that those tools did not exist until programmers had proven that refactoring was helpful, which pretty much required them to work without tools. Many developers applied the recipes from the <cite>Refactoring<\/cite> book by hand for years without any tool support.<\/p>\n<p>Don&#8217;t get me wrong, tools that automate the mechanics of refactoring does simplify the process. Having the boring, mechanical parts of a simple refactor handled by your editor-of-choice definitely makes you more likely to make those changes. But, it&#8217;s possible to refactor without any tools. The most important part of the process is that you think about how you are improving your design, not about which tool does the changes. Just as importantly, you should be able to apply refactorings that your tool does not support. The thinking behind the change is the important part.<\/p>\n<h2 class=\"subhead\">Conclusion<\/h2>\n<p>The programming community has been aware of the concept of refactoring for years now and the practice has become much more wide-spread. Like any other practice in programming, it is often necessary to go back and re-assess what we know and how we practice. Hopefully, some of these points will help you do just that.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently heard an interview with Martin Fowler on the Ruby Rogues podcast. He pointed out a few things about the process of refactoring that I haven&#8217;t thought of in a while. Based on that interview and what I&#8217;ve read and learned elsewhere about refactoring in the past few years, I decided there are a\u2026 <span class=\"read-more\"><a href=\"https:\/\/blog.gwadej.org\/programmer-musings\/2014\/11\/some-thoughts-on-refactoring\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[279,303,345],"_links":{"self":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts\/263"}],"collection":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/comments?post=263"}],"version-history":[{"count":1,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts\/263\/revisions"}],"predecessor-version":[{"id":1363,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts\/263\/revisions\/1363"}],"wp:attachment":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/media?parent=263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/categories?post=263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/tags?post=263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}