CINXE.COM

Refactoring

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta content = 'uft-8' name = 'charset'></meta> <title>Refactoring</title> <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> <meta content = 'Refactoring Home Page' property = 'og:title'></meta> <meta content = 'http://refactoring.com' property = 'og:url'></meta> <meta content = 'Introduction to the technique of refactoring and online catalog of refactorings' property = 'og:description'></meta> <meta content = 'http://refactoring.com/twitter-card.png' property = 'og:image'></meta> <meta content = 'website' property = 'og:type'></meta> <meta content = 'summary_large_image' name = 'twitter:card'></meta> <link href = 'refactoring-home.css' rel = 'stylesheet' type = 'text/css'></link> </head> <body><div id="banner"><a href="http://refactoring.com" class="banner-logo"><img src="/banner-logo.png" width="200"></img></a><div class="red-rect"></div><div class="photo"></div><div class="main-navigation"><ul><li class="catalog"><a href="/catalog">Catalog</a></li></ul></div><div class="mfcom-navigation"><ul><li>part of <a href="https://martinfowler.com" title="main site">martinfowler.com</a></li><li><a href="https://martinfowler.com/feed.atom" class="icon icon-rss" title="feed"></a></li><li><a href="http://www.twitter.com/martinfowler" class="icon icon-twitter" title="Twitter stream"></a></li></ul></div> <div class="search"> <!-- SiteSearch Google --> <form method="GET" action="https://www.google.com/search"> <input type="hidden" name="ie" value="UTF-8"></input> <input type="hidden" name="oe" value="UTF-8"></input> <input class="field" type="text" name="q" size="15" maxlength="255" value=""></input> <button class="button" type="submit" name="btnG" value=" " title="Search"></button> <input type="hidden" name="domains" value="refactoring.com"></input> <input type="hidden" name="sitesearch" value=""></input> <input type="hidden" name="sitesearch" value="refactoring.com"></input> </form> </div> <div class="menu-button navmenu-button"><a href="#navmenu-bottom" class="icon icon-bars"></a></div></div> <nav id = 'top-navmenu'> <nav class="navmenu"> <div class="nav-head"> <div class="search"> <!-- SiteSearch Google --> <form method="GET" action="https://www.google.com/search"> <input type="hidden" name="ie" value="UTF-8"> <input type="hidden" name="oe" value="UTF-8"> <input class="field" type="text" name="q" size="15" maxlength="255" value=""> <button class="button" type="submit" name="btnG" value=" " title="Search"></button> <input type="hidden" name="domains" value="martinfowler.com"> <input type="hidden" name="sitesearch" value=""> <input type="hidden" name="sitesearch" value="martinfowler.com"> </form> </div> <div class="closediv"> <span class="close" title="close"></span> </div> </div> <div class="nav-body"> <div class="topics"> <h2>Topics</h2> <p><a href="//martinfowler.com/architecture">Architecture</a></p> <p><a href="https://refactoring.com">Refactoring</a></p> <p><a href="//martinfowler.com/agile.html">Agile</a></p> <p><a href="//martinfowler.com/delivery.html">Delivery</a></p> <p><a href="//martinfowler.com/microservices">Microservices</a></p> <p><a href="//martinfowler.com/data">Data</a></p> <p><a href="//martinfowler.com/testing">Testing</a></p> <p><a href="//martinfowler.com/dsl.html">DSL</a></p> </div> <div class="about"> <h2>about me</h2> <p><a href="//martinfowler.com/aboutMe.html">About</a></p> <p><a href="//martinfowler.com/books">Books</a></p> <p><a href="//martinfowler.com/faq.html">FAQ</a></p> </div> <div class="content"> <h2>content</h2> <p><a href="//martinfowler.com/videos.html">Videos</a></p> <p><a href="//martinfowler.com/tags">Content Index</a></p> <p><a href="//martinfowler.com/articles/eurogames">Board Games</a></p> <p><a href="//martinfowler.com/photos">Photography</a></p> </div> <div class="tw"> <h2>Thoughtworks</h2> <p><a href="https://thoughtworks.com/insights">Insights</a></p> <p><a href="https://thoughtworks.com/careers">Careers</a></p> <p><a href="https://thoughtworks.com/radar">Radar</a></p> </div> <div class="feeds"> <h2>follow</h2> <p><a href="//martinfowler.com/feed.atom">RSS</a></p> <p><a href="https://toot.thoughtworks.com/@mfowler">Mastodon</a></p> <p><a href="https://www.linkedin.com/in/martin-fowler-com/">LinkedIn</a></p> <p><a href="https://www.twitter.com/martinfowler">X (Twitter)</a></p> <p><a href="https://boardgamegeek.com/blog/13064/martins-7th-decade">BGG</a></p> </div> </div> </nav> </nav> <main> <section class = 'lede'> <section class = 'main'> <p><b>Refactoring</b> is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.</p> <p> Its heart is a series of small behavior preserving transformations. Each transformation (called a “refactoring”) does little, but a sequence of these transformations can produce a significant restructuring. Since each refactoring is small, it's less likely to go wrong. The system is kept fully working after each refactoring, reducing the chances that a system can get seriously broken during the restructuring.</p> </section> <section class = 'side'> <p><a href = 'http://martinfowler.com'><img alt = 'photo of Martin Fowler' src = 'mf-bw.jpg' style = 'max-width:100px'></img></a></p> <p><a href = 'http://martinfowler.com'>Martin Fowler</a></p> </section> </section> <section class = 'row body'> <section> <section id = 'RefactoringLowersTheCostOfEnhancements'> <h2>Refactoring lowers the cost of enhancements</h2> <p>When a software system is successful, there is always a need to keep enhancing it, to fix problems and add new features. After all, it's called <i>soft</i>ware for a reason! But the nature of a code-base makes a big difference on how easy it is to make these changes. Often enhancements are applied on top of each other in a manner that makes it increasingly harder to make changes. Over time new work slows to a crawl. To combat this change, it's important to refactor code so that added enhancements don't lead to unnecessary complexity.</p> <h2>Refactoring is a part of day-to-day programming</h2> <p>Refactoring isn't a special task that would show up in a project plan. Done well, it's a regular part of programming activity. When I need to add a new feature to a codebase, I look at the existing code and consider whether it's structured in such a way to make the new change straightforward. If it isn't, then I refactor the existing code to make this new addition easy. By refactoring first in this way, I usually find it's faster than if I hadn't carried out the refactoring first. </p> <p>Once I've done that change, I then add the new feature. Once I've added a feature and got it working, I often notice that the resulting code, while it works, isn't as clear as it could be. I then refactor it into a better shape so that when I (or someone else) return to this code in a few weeks time, I won't have to spend time puzzling out how this code works.</p> <p>When modifying a program, I'm often looking elsewhere in the code, because much of what I need to do may already be encoded in the program. This code may be functions I can easily call, or hidden inside larger functions. If I struggle to understand this code, I refactor it so I won't have to struggle again next time I look at it. If there's some functionality buried in there that I need, I refactor so I can easily use it.</p> <h2>Automated tools are helpful, but not essential</h2> <p>When I wrote the first edition of Refactoring, back in the late 90's, there were few automated tools that supported Refactoring. Now many languages have IDEs which automate many common refactorings. These are a really valuable part of my toolkit allowing me to carry out refactoring faster. But such tools aren't essential - I often work in programming languages without tool support, in which case I rely on taking small steps, and using frequent testing to detect mistakes. </p> </section> </section> <section id = 'TheCatalog'> <h2>The Catalog</h2> <p>The primary content of this site is the <a href = 'catalog'>online catalog of refactorings</a>. This lists the refactorings in the second edition, together with summary information about the refactorings.</p> <h2>The Book</h2> <p><img class = 'side-book' src = 'refact2.jpg'></img>To learn more about refactoring, the natural starting point is <a href = 'http://martinfowler.com/books/refactoring.html'>my refactoring book</a>, now in its second edition. I wrote the original edition in 1997-9 when Refactoring was a little-known technique. When I updated it eighteen years later, refactoring had become a regular tool for any skilled programmer. However new people regularly enter our profession and need to learn about refactoring. This book helps them to learn, and for experienced developers to pass on their skills.</p> <p>The examples in the second edition are in JavaScript, but the refactorings are applicable in any language. With the original books (whose examples were in Java) many developers found it straightforward to take the examples and apply them to whatever languages they use.</p> <p>If you have the book you can <a href = 'https://martinfowler.com/articles/access-refactoring-web-edition.html'>access the web edition of the book</a>, which is the canonical edition. It includes several refactorings not in the book, as well as an expanded example.</p> <div class = 'web-ed'><a href = 'https://memberservices.informit.com/my_account/webedition/9780135425664/html/index.html?partner=53'><img alt = 'open in web edition' src = '/in-web-ed.png' title = 'open in web edition'></img></a> <p><a href = 'https://martinfowler.com/articles/access-refactoring-web-edition.html'>How do I access the web edition?</a></p> </div> </section> </section> <section class = 'defs-section' id = 'Definition'> <h2>Definition</h2> <p>In the book, I make the following definition of &#x201C;refactoring&#x201D;</p> <div class = 'definitions'> <p class = 'def'> <span class = 'form'>noun: </span> a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior</p> <p class = 'def'> <span class = 'form'>verb: </span> to restructure software by applying a series of refactorings without changing its observable behavior.</p> </div> <p>Refactoring isn't another word for cleaning up code - it specifically defines <i>one</i> technique for improving the health of a code-base. I use “restructuring” as a more general term for reorganizing code that may incorporate other techniques.</p> </section> <section class = 'mfcom' id = 'OnMartinfowler.com'> <h2>On martinfowler.com</h2> <p>My main website contains more of my writing on refactoring. In particular it contains several longer examples, mostly written just before the second edition of the book:</p> </section> <section class = 'card-box'> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/refactoring-external-service.html'>Refactoring code that accesses external services</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/refactoring-external-service/card.png'></img></p> <p class = 'abstract'> When I write code that deals with external services, I find it valuable to separate that access code into separate objects. Here I show how I would refactor some congealed code into a common pattern of this separation. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>17 Feb 2015</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/refactoring-external-service.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/object%20collaboration%20design.html>object collaboration design</a></span> <span class = 'tag-link'><a href = /tags/programming%20style.html>programming style</a></span> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> <span class = 'tag-link'><a href = /tags/application%20architecture.html>application architecture</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/refactoring-dependencies.html'>Refactoring Module Dependencies</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/refactoring-dependencies/ref-dep_sl.png'></img></p> <p class = 'abstract'> As a program grows in size it's important to split it into modules, so that you don't need to understand all of it to make a small modification. Often these modules can be supplied by different teams and combined dynamically. In this refactoring essay I split a small program using Presentation-Domain-Data layering. I then refactor the dependencies between these modules to introduce the Service Locator and Dependency Injection patterns. These apply in different languages, yet look different, so I show these refactorings in both Java and a classless JavaScript style. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>13 Oct 2015</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/refactoring-dependencies.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> <span class = 'tag-link'><a href = /tags/API%20design.html>API design</a></span> <span class = 'tag-link'><a href = /tags/application%20architecture.html>application architecture</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/refactoring-adaptive-model.html'>Refactoring to an Adaptive Model</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/refactoring-adaptive-model/sketch-01.png'></img></p> <p class = 'abstract'> Most of our software logic is written in our programming languages, these give us the best environment to write and evolve such logic. But there are circumstances when it's useful to move that logic into a data structure that our imperative code can interpret - what I refer to as an adaptive model. Here I'll show some product selection logic in JavaScript and show how it can be refactored to a simple production rule system encoded in JSON. This JSON data allows us to share this selection logic between devices using different programming languages and to update this logic without updating the code on these devices. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>19 Nov 2015</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/refactoring-adaptive-model.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> <span class = 'tag-link'><a href = /tags/domain%20specific%20language.html>domain specific language</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/refactoring-video-store-js/'>Refactoring a JavaScript video store</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/refactoring-video-store-js/video-js_card.png'></img></p> <p class = 'abstract'> The simple example of calculating and formatting a bill for a video store opened my refactoring book in 1999. If done in modern JavaScript, there are several directions you could take the refactoring. I explore four here: refactoring to top level functions, to a nested function with a dispatcher, using classes, and transformation using an intermediate data structure. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>18 May 2016</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/refactoring-video-store-js/'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/class-too-large.html'>Refactoring: This class is too large</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/class-too-large/MasterPlan.png'></img></p> <p class = 'abstract'> In this article I walk through a set of refactorings from a real code base. This is not intended to demonstrate perfection, but it does represent reality. </p> <div class = 'meta'> <p class = 'credits'>by Clare Sudbery</p> <p class = 'date'>14 Apr 2020</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/class-too-large.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/object%20collaboration%20design.html>object collaboration design</a></span> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/refactoring-document-load.html'>Refactoring Code to Load a Document</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/refactoring-document-load/ref-doc_encap.png'></img></p> <p class = 'abstract'> Much modern web server code talks to upstream services which return JSON data, do a little munging of that JSON data, and send it over to rich client web pages using fashionable single page application frameworks. Talking to people working with such systems I hear a fair bit of frustration of how much work they need to do to manipulate these JSON documents. Much of this frustration could be avoided by encapsulating a combination of loading strategies. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>17 Dec 2015</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/refactoring-document-load.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/refactoring-pipelines.html'>Refactoring with Loops and Collection Pipelines</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/refactoring-pipelines/card.png'></img></p> <p class = 'abstract'> The loop is the classic way of processing collections, but with the greater adoption of first-class functions in programming languages the collection pipeline is an appealing alternative. In this article I look at refactoring loops to collection pipelines with a series of small examples. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>14 Jul 2015</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/refactoring-pipelines.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/object%20collaboration%20design.html>object collaboration design</a></span> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/replaceThrowWithNotification.html'>Replacing Throwing Exceptions with Notification in Validations</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/sketch.png'></img></p> <p class = 'abstract'> If you're validating some data, you usually shouldn't be using exceptions to signal validation failures. Here I describe how I'd refactor such code into using the Notification pattern. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>9 Dec 2014</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/replaceThrowWithNotification.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> </p> </div> </div> </div> <div class = 'article-card'> <h3><a href = 'https://martinfowler.com/articles/preparatory-refactoring-example.html'>An example of preparatory refactoring</a></h3> <div class = 'card-body'> <p class = 'card-image'><img src = 'https://martinfowler.com/articles/preparatory-refactoring-example/card.png'></img></p> <p class = 'abstract'> A simple example of how it can be easier to make a change by first refactoring the code to make the change easy. </p> <div class = 'meta'> <p class = 'credits'>by Martin Fowler</p> <p class = 'date'>5 Jan 2015</p> <p class = 'more'><a href = 'https://martinfowler.com/articles/preparatory-refactoring-example.html'>Read more…</a></p> <p class = 'type article'>article</p> <p class = 'tags'> <span class = 'tag-link'><a href = /tags/refactoring.html>refactoring</a></span> </p> </div> </div> </div> </section> </main> <nav id = 'bottom-navmenu'> <nav class="navmenu"> <div class="nav-head"> <div class="search"> <!-- SiteSearch Google --> <form method="GET" action="https://www.google.com/search"> <input type="hidden" name="ie" value="UTF-8"> <input type="hidden" name="oe" value="UTF-8"> <input class="field" type="text" name="q" size="15" maxlength="255" value=""> <button class="button" type="submit" name="btnG" value=" " title="Search"></button> <input type="hidden" name="domains" value="martinfowler.com"> <input type="hidden" name="sitesearch" value=""> <input type="hidden" name="sitesearch" value="martinfowler.com"> </form> </div> <div class="closediv"> <span class="close" title="close"></span> </div> </div> <div class="nav-body"> <div class="topics"> <h2>Topics</h2> <p><a href="//martinfowler.com/architecture">Architecture</a></p> <p><a href="https://refactoring.com">Refactoring</a></p> <p><a href="//martinfowler.com/agile.html">Agile</a></p> <p><a href="//martinfowler.com/delivery.html">Delivery</a></p> <p><a href="//martinfowler.com/microservices">Microservices</a></p> <p><a href="//martinfowler.com/data">Data</a></p> <p><a href="//martinfowler.com/testing">Testing</a></p> <p><a href="//martinfowler.com/dsl.html">DSL</a></p> </div> <div class="about"> <h2>about me</h2> <p><a href="//martinfowler.com/aboutMe.html">About</a></p> <p><a href="//martinfowler.com/books">Books</a></p> <p><a href="//martinfowler.com/faq.html">FAQ</a></p> </div> <div class="content"> <h2>content</h2> <p><a href="//martinfowler.com/videos.html">Videos</a></p> <p><a href="//martinfowler.com/tags">Content Index</a></p> <p><a href="//martinfowler.com/articles/eurogames">Board Games</a></p> <p><a href="//martinfowler.com/photos">Photography</a></p> </div> <div class="tw"> <h2>Thoughtworks</h2> <p><a href="https://thoughtworks.com/insights">Insights</a></p> <p><a href="https://thoughtworks.com/careers">Careers</a></p> <p><a href="https://thoughtworks.com/radar">Radar</a></p> </div> <div class="feeds"> <h2>follow</h2> <p><a href="//martinfowler.com/feed.atom">RSS</a></p> <p><a href="https://toot.thoughtworks.com/@mfowler">Mastodon</a></p> <p><a href="https://www.linkedin.com/in/martin-fowler-com/">LinkedIn</a></p> <p><a href="https://www.twitter.com/martinfowler">X (Twitter)</a></p> <p><a href="https://boardgamegeek.com/blog/13064/martins-7th-decade">BGG</a></p> </div> </div> </nav> </nav> <footer id="page-footer"> <div class="tw-logo"> <a href="http://www.thoughtworks.com"> <img src="//martinfowler.com/thoughtworks_white.png"> </a> </div> <div class="menu-button"> <div class="icon-bars navmenu-button"></div> </div> <div class="copyright"> <p>© Martin Fowler | <a href="http://www.thoughtworks.com/privacy-policy">Privacy Policy</a> | <a href="//martinfowler.com/aboutMe.html#disclosures">Disclosures</a></p> </div> </footer> <!-- Google Analytics --> <!-- old Google Universal --> <script> window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date; ga('create', 'UA-17005812-2', 'auto'); ga('send', 'pageview'); </script> <script async src="https://www.google-analytics.com/analytics.js"></script> <!-- New Google GA4 --> <!-- global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-6D51F4BDVF"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-6D51F4BDVF'); </script> <!-- End Google Analytics --> <script src = '//martinfowler.com/jquery-1.11.3.min.js' type = 'text/javascript'></script> <script src = '//martinfowler.com/mfcom.js' type = 'text/javascript'></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10