Why You Should Refactor Your Software
Summary
This episode of Developer Tea provides a comprehensive introduction to refactoring in software development. Host Jonathan Cottrell begins by defining refactoring according to Martin Fowler as “the process of changing a software system in such a way that it does not alter the external behavior of the code, yet it improves its internal structure.” He emphasizes that refactoring should be done with passing tests as a safety net, allowing developers to change underlying code while ensuring external interfaces remain unchanged.
Cottrell outlines five key situations when developers should consider refactoring their code. The first is eliminating repetition by creating methods or variables to hold repeated code. The second involves improving unclear or confusing variable naming, acknowledging that naming things is one of the most difficult problems in computer science. The third situation occurs when methods become too long (typically 5-15 lines), suggesting they should be broken into smaller, more focused methods.
The fourth reason to refactor is when classes contain too many methods, making them difficult to reason about. Cottrell suggests classes should ideally be around 100 lines with 5-25 methods, though he acknowledges there’s disagreement on exact numbers. The final reason is when methods have side effects or perform multiple responsibilities, which makes code difficult to test and maintain. He provides the example of a user signup method that also charges the user, suggesting these should be separate operations.
Throughout the episode, Cottrell emphasizes that refactoring is fundamentally about human factors rather than functionality. The goal is to make code easier to read, maintain, and extend for both the original developer and others who will work with the code in the future. He positions refactoring as an ongoing part of the development process rather than a separate activity, quoting Martin Fowler’s perspective that “you don’t decide to refactor, you refactor as a part of the development process.”
Cottrell concludes by recommending Martin Fowler’s book “Refactoring,” which uses Java as its principal language but has concepts applicable to other object-oriented languages, as well as a Ruby-specific version. He stresses that refactoring should only be done after establishing a solid test suite that describes the code’s intended behavior, allowing developers to confidently improve code structure without breaking functionality.
Recommendations
Books
- Refactoring by Martin Fowler — The book uses Java as its principal language to teach refactoring concepts that apply to object-oriented programming. Cottrell mentions going through the Ruby version himself and finding it enlightening.
- Ruby version of Refactoring by Martin Fowler — A Ruby-specific adaptation of Fowler’s refactoring book that applies the same principles to Ruby programming. Cottrell recommends it for those wanting to learn more about refactoring in Ruby.
Tools
- Hired.com — A job platform where software engineers and designers can receive multiple job offers with salary and equity details upfront. The host mentions a special offer for Developer Tea listeners that doubles the signing bonus.
Topic Timeline
- 00:00:00 — Introduction to refactoring and Martin Fowler’s definition — Jonathan Cottrell introduces the topic of refactoring software. He explains Martin Fowler’s definition of refactoring as changing a software system without altering external behavior while improving internal structure. He uses the example of an API where endpoints remain unchanged but underlying code improves.
- 00:01:26 — The role of tests in safe refactoring — Cottrell discusses how tests enable safe refactoring by ensuring external behavior remains unchanged. He explains that developers should start with passing tests, make code changes, and return to a passing state without modifying tests. This safety net allows developers to break code temporarily during refactoring.
- 00:02:45 — First reason to refactor: eliminating repetition — The host presents the first key reason to refactor: when code contains repetition. He suggests creating methods or variables to encapsulate repeated logic. This makes code more maintainable and reduces duplication, which is a common refactoring scenario.
- 00:04:08 — Second reason: improving unclear variable naming — Cottrell addresses the challenge of naming in programming, calling it “one of the most difficult problems in computer science.” He explains that entire refactoring sessions might focus on renaming variables to make them clearer for both the original developer and others reading the code.
- 00:05:14 — Third reason: methods that are too long — The episode discusses method length as a refactoring trigger. Cottrell suggests ideal methods are 5-15 lines long, though he personally prefers 3-5 lines. Breaking long methods into smaller, well-named methods improves readability and makes code more explicit about its steps.
- 00:08:46 — Fourth reason: classes with too many methods — Cottrell explains that classes should be reasonably sized (around 100 lines with 5-25 methods) to be comprehensible. When classes grow too large, methods should be moved to new classes or modules. This applies to both object-oriented programming and JavaScript modules.
- 00:10:24 — Fifth reason: methods with side effects or multiple responsibilities — The final refactoring reason discussed is when methods have side effects or perform multiple jobs. Cottrell uses the example of a user signup method that also charges users, suggesting these should be separate. Single-responsibility methods are easier to test and maintain.
- 00:12:27 — Refactoring as a human-centered practice — Cottrell emphasizes that refactoring addresses human problems rather than functional ones. The goal is to make code easier to read, maintain, and extend for developers. He notes that refactoring should be an ongoing part of development, not a separate decision.
- 00:14:21 — Recommendation of Martin Fowler’s Refactoring book — The host recommends Martin Fowler’s book “Refactoring,” which uses Java as its principal language but has concepts applicable to other object-oriented languages. He also mentions a Ruby-specific version and notes he’s currently reading it himself, finding it enlightening.
Episode Info
- Podcast: Developer Tea
- Author: Jonathan Cutrell
- Category: Technology Business Careers Society & Culture
- Published: 2015-07-22T07:00:00Z
- Duration: 00:16:00
References
- URL PocketCasts: https://podcast-api.pocketcasts.com/podcast/full/cbe9b6c0-7da4-0132-e6ef-5f4c86fd3263/846b2371-1c78-426d-ab63-23c5c138bf93
- Episode UUID: 846b2371-1c78-426d-ab63-23c5c138bf93
Podcast Info
- Name: Developer Tea
- Type: episodic
- Site: http://www.developertea.com
- UUID: cbe9b6c0-7da4-0132-e6ef-5f4c86fd3263
Transcript
[00:00:00] Hey, everyone, and welcome to Developer Tea.
[00:00:04] My name is Jonathan Cottrell, and today I’m going to be talking to you about refactoring
[00:00:08] your software.
[00:00:09] I’m going to give you a five-minute overview, just a high-level overview of what exactly
[00:00:14] refactoring is and when you might want to refactor your software.
[00:00:23] According to Martin Fowler, now, if you don’t know who Martin Fowler is, go and Google him
[00:00:28] after you listen to this episode.
[00:00:30] Martin is partially responsible for the Agile Manifesto, which was written back in 2001,
[00:00:35] but Martin defines refactoring as the process of changing a software system in such a way
[00:00:43] that it does not alter the external behavior of the code, yet it improves its internal
[00:00:48] structure.
[00:00:49] So imagine that you are building an API, for example, and the API has an interface that
[00:00:57] users can see.
[00:00:58] Or perhaps you’re creating another product that consumes that API.
[00:01:02] To refactor that API, you would not change the endpoints of the API that those users
[00:01:09] consume or that your product consumes.
[00:01:12] Instead, you would only change the underlying code.
[00:01:15] Perhaps the most common way to ensure that you are not changing the external API or the
[00:01:21] external interface to your code is to have tests that run against that code.
[00:01:26] And when you refactor,
[00:01:28] you would start with passing tests, so you would look at your code and make sure that
[00:01:32] it’s working and that all of your tests are passing when you start out, and then you would
[00:01:38] change the code and make sure that you get it back to a passing state.
[00:01:44] In other words, it’s very likely that in the process of refactoring your code, you’re going
[00:01:49] to break something, and so you refactor the code and change it to get it back to a green
[00:01:55] state.
[00:01:56] You wouldn’t change your tests, though.
[00:01:59] That’s the important part of that, is that if you have a test suite, if you have a number
[00:02:03] of tests that are running against your code and you want to refactor your code, don’t
[00:02:08] change your tests.
[00:02:09] Only change your code one piece at a time until your code is passing all of those tests.
[00:02:15] Now what exactly is refactoring?
[00:02:18] We’ve said that refactoring is changing underlying code and that it’s not changing the external
[00:02:24] system.
[00:02:25] The API, for instance.
[00:02:26] Perhaps you have a class that you can interact with from other files from other classes.
[00:02:32] You wouldn’t want to change the class methods or the method names or the actual effect of
[00:02:38] those methods, but rather you want to change the underlying code.
[00:02:42] Now why would you want to change the underlying code?
[00:02:45] Now I’m going to ask you to do something that I normally wouldn’t ask you to do.
[00:02:48] I’m going to ask you to pause the podcast and think about why you might want to change
[00:02:53] the underlying code.
[00:02:55] Why would you change code?
[00:02:56] Why would you change the underlying code that already is passing tests, already is
[00:02:59] functioning properly, and you aren’t even changing that function?
[00:03:03] Why would you change the underlying code?
[00:03:05] Go ahead and pause the podcast and think about why you might want to change that underlying
[00:03:10] code.
[00:03:11] Now I’m sure you’ve come up with some good reasons if you paused the podcast.
[00:03:16] Even if you didn’t, maybe you already have good reasons in mind as to why you would want
[00:03:20] to refactor code that is already working.
[00:03:24] Perhaps the most obvious reason to refactor code is that you’ve already changed the underlying
[00:03:25] code.
[00:03:26] The reason you want to refactor your code is in order to avoid repetition.
[00:03:31] When you notice that you are repeating the same types of code over and over, then it’s
[00:03:35] likely that you need to create some kind of method to offset that specific repeated piece
[00:03:43] of code.
[00:03:44] So whether you create some kind of variable to hold some information that you were repeating
[00:03:49] previously, or perhaps you create a new method like a private method on a class to hold some
[00:03:55] information that you’re reusing.
[00:03:56] This is a very common reason for refactoring your code.
[00:04:02] Another very common reason is when your variable naming is confusing or unclear.
[00:04:08] This seems trivial, but perhaps one of the most difficult problems in computer science
[00:04:13] is naming things.
[00:04:14] We’ve talked about this on the show before, and it’s a pretty famous quote.
[00:04:19] Naming things is a very difficult thing to do, and so it may come as no surprise that
[00:04:25] an entire refactoring session may be totally dedicated to renaming variables to something
[00:04:31] that makes a little bit more sense.
[00:04:33] So make sure that you are naming your variables something clear, or if you are in a refactoring
[00:04:39] session, rename variables.
[00:04:42] It’s totally fine to rename variables, especially if they are localized to whatever function
[00:04:47] or method you are performing at that moment.
[00:04:50] So make sure your variable naming is clear.
[00:04:53] Not only to you.
[00:04:54] But also to the person who is reading your code.
[00:04:58] At this point in time in programming history, variables are cheap.
[00:05:03] Make the variable explicitly clear as to what it is and how it fits in that function or
[00:05:08] that method.
[00:05:10] Another example of a time where you may want to refactor your code is when your methods
[00:05:14] are getting entirely too long.
[00:05:16] Now a good method typically, at least in Ruby, is going to be somewhere between 5 and 15
[00:05:22] lines long.
[00:05:23] Now there’s some arguments over there.
[00:05:24] There’s some really strong opinions in this arena.
[00:05:28] For me, I like to keep methods down to about 3 to 5 lines when possible.
[00:05:33] And usually if I wanted to, I could write those methods in one or two lines.
[00:05:39] But I use those 3 through 5 lines to make it a little bit more clear.
[00:05:44] Now we said previously that you don’t want to change the structure of your class from
[00:05:49] the outside looking in.
[00:05:50] So you wouldn’t want to rename your methods necessarily.
[00:05:53] But instead, you want to break them up into separate methods that you can compose together.
[00:05:59] What this allows you to do is be more explicit about the steps that you’re taking.
[00:06:04] The entire point of these methods being short is that you can be more abstract about the
[00:06:10] language that you’re using and it makes your code much more reasonable and readable for
[00:06:15] somebody who’s coming from the outside in.
[00:06:18] So create methods that explain what they do in their naming structure.
[00:06:23] And then make sure those methods are short enough.
[00:06:25] And typically that means between 5 and 15 lines.
[00:06:29] I’m going to take a quick break for a sponsor and then I’m going to come back and give you
[00:06:33] two other times when you might want to refactor your code and then some reasoning behind those
[00:06:40] situations and why you would want to refactor your code in those situations.
[00:06:49] I’m so excited to tell you about today’s sponsor.
[00:06:51] Because there’s a lot to learn.
[00:06:52] There’s opportunity for almost anyone with today’s sponsor and that is Hired.com.
[00:06:58] On Hired, software engineers and designers can get five or more job offers in a given
[00:07:04] week.
[00:07:05] Now each of these offers has salary and equity built in up front and there are both full-time
[00:07:10] and contract offers and opportunities available on Hired.
[00:07:14] Users can view the offers from over 2,500 companies of all sizes from startups to large
[00:07:21] public companies.
[00:07:22] And then they can accept or reject the offers before ever talking to any company.
[00:07:27] So there’s never any obligations and it’s totally free to use.
[00:07:31] It’s 100% free to use.
[00:07:33] Now normally if you get a job through Hired, they’ll give you a $2,000 thank you bonus.
[00:07:39] But if you use the special link for developer T that will be in the show notes, Hired will
[00:07:43] double that bonus to $4,000 if you accept a job.
[00:07:47] That’s Hired.com slash developer T. Now even if you aren’t looking for a job, you can get
[00:07:52] a $1,337 bonus if you accept a job through Hired.
[00:07:53] So if you know another engineer or a designer who is, you can refer them to Hired and if
[00:07:59] they accept a job on Hired, you will get a $1,337 bonus.
[00:08:05] That is a huge opportunity pretty much for anyone.
[00:08:08] So go and check it out, Hired.com slash developer T.
[00:08:15] Today I’ve been talking about refactoring, I’ve given you a couple of situations where
[00:08:20] you would probably want to refactor.
[00:08:21] One is when you’ve noticed that you’re using a lot of repetition in your code.
[00:08:28] The second one is when your variable naming is confusing or perhaps it’s unclear.
[00:08:34] The third one is when method definitions are getting too long.
[00:08:37] So when a single method is growing to 15, 20, 30 lines long, of course this is a time
[00:08:43] when you might want to consider refactoring your code.
[00:08:46] The fourth one is when your classes start to have too many methods.
[00:08:51] So the idea here is that your classes should be somewhere around 100 lines long, and again
[00:08:56] there’s a lot of disagreement on this point, but around 100 lines long is one opinion out
[00:09:03] there.
[00:09:04] I actually hold to this opinion as well.
[00:09:07] So you’re looking at somewhere between 5 and 25 methods in a given class.
[00:09:13] Now that may seem really small to you, but the reality is it’s going to be much easier
[00:09:18] for you to deal with these classes.
[00:09:19] So if you’re looking at a lot of different methods in a given class, you might want to
[00:09:20] think about how you’re going to deal with these classes.
[00:09:21] If you can reason about everything in that class in one go.
[00:09:25] If you can look at that class and see all of the methods that that class contains.
[00:09:31] Of course we’re talking specifically about object-oriented programming, but this is true
[00:09:36] for JavaScript as well.
[00:09:38] When you have a module that holds a lot of functions, for example, it’s very likely that
[00:09:43] you could move those functions into other modules and benefit from the simplicity that
[00:09:48] you gain.
[00:09:49] So how do you do this?
[00:09:50] Well, one of the best ways to handle this is just to simply create more classes.
[00:10:00] In a future episode, we might cover ways that you can discover which methods need to be
[00:10:05] moved into a different class, but there’s certainly a lot of material available in determining
[00:10:11] when and where to move methods out of one class or out of a module perhaps into a new
[00:10:18] module or class.
[00:10:20] I’m going to give you one final reason that you may want to refactor your code.
[00:10:24] Again, this show is not intended to encapsulate all of the reasons why you might want to refactor,
[00:10:32] but just to give you an idea, and a starting point for thinking about why and when you
[00:10:37] would want to refactor your code.
[00:10:39] The final reason would be when the methods have side effects or are doing more than one
[00:10:44] job.
[00:10:45] This is just one example of this.
[00:10:47] If you are signing up a user and trying to refactor your code, you might be thinking,
[00:10:48] like, I’m going to refactor this one.
[00:10:49] This is just some just a few of the things that are in your character.
[00:10:50] charging them in the same method. It’s very likely that you’re going to want to eventually be able to
[00:10:56] sign up a user and not charge them. And if you only have one method available, then you won’t
[00:11:02] be able to do this. And it also makes your code very difficult to test. It’s hard to sign up a
[00:11:08] fake user. Another example of why this is a bad situation to be in is because if you are duplicating
[00:11:16] your data, if you are pulling down the production database and using it locally to test things in
[00:11:23] your local environment, and you rerun all that data or you seed a bunch of users into your database,
[00:11:30] then you recharge those same users. That’s a bad situation to be in. So you want to make sure that
[00:11:36] your code has only one responsibility per method at least. And many people subscribe to the idea
[00:11:44] that each class should have one method. And so you want to make sure that you have one method.
[00:11:46] have its own responsibility. So in that previous reason for refactoring that I said,
[00:11:51] when your classes start to have too many methods, the reasoning behind that is that we want classes
[00:11:57] to only have one sole responsibility, that they should be simple. And when that sole responsibility
[00:12:03] starts to grow out of scope, that’s when you want to create a new class. When you notice that your
[00:12:10] methods are doing more than one thing, or if they have side effects that are difficult to test,
[00:12:15] that is a bad situation to be in. So you want to make sure that you have one method. And when you
[00:12:16] that is a point at which you want to refactor your code, you want to make sure that each method
[00:12:21] only does one thing at a time. Now, one final note that I want to make about refactoring is that
[00:12:27] refactoring is not about the functionality of your code. As I said previously, the point is not to
[00:12:34] make your code functionally different, but rather it is to make your code easier to maintain and to
[00:12:41] extend in the future. And that is entirely a human problem. And that is a human problem. And that is
[00:12:46] a human problem. And that is a human problem. And that is a human problem. And that is a human problem.
[00:12:46] You refactor for yourself and you refactor for other developers who are going to come in and look at
[00:12:52] your code and change it in the future or extend it, or if they just want to reason about it, to learn
[00:12:59] from it. So that’s another signifier of when you want to refactor your code. That is when you
[00:13:06] recognize that your code is difficult to read, or when somebody else comes in and says this code is
[00:13:12] difficult to extend or maintain, or perhaps you don’t want to refactor your code. That is when you
[00:13:16] recognize it’s difficult to test or it’s difficult to write tests for. All of these are reasons why
[00:13:21] refactoring is an important part of your process. It’s something that you’re constantly going to do.
[00:13:28] Martin Fowler says that you don’t decide to refactor, you refactor as a part of the
[00:13:33] development process. So in a nutshell, remember, refactoring happens after you have working code
[00:13:42] that you have tests for. Once you have tests that describe your
[00:13:46] work, you can refactor your code. And that’s when you have tests that describe your work.
[00:13:46] Then you can move forward and rewrite that code to be more readable by other humans and easier to
[00:13:53] extend without having to duplicate code and without having to have a human sit down and explain their
[00:14:01] reasoning for why they did what they did or why they named something what they named it. Refactoring
[00:14:07] helps you avoid situations where another programmer or you later on down the road are having a lot of
[00:14:15] difficulty reading and extending your code. If you’re interested in learning a bit more about
[00:14:21] refactoring and how you would go about the process of refactoring, you can read a book by Martin
[00:14:27] Fowler called Refactoring. It uses Java as its principal language. Of course, that applies to
[00:14:34] other object-oriented languages. Martin Fowler also wrote a Ruby version of this book. It’s
[00:14:41] relatively ubiquitous, so it’s likely that you’ve either seen this cover or you’ve heard about it.
[00:14:45] You can find links in the show notes to these two books. I myself am going through the Ruby version
[00:14:55] of Martin’s book. It is certainly enlightening, so I highly recommend that you check it out
[00:14:59] if you’d like to learn more about refactoring.
[00:15:15] Thank you so much for listening to this episode. If you or someone you know is looking for a job as
[00:15:21] a designer or a developer, go and check out today’s sponsor, Hired.com. Incredible opportunities from
[00:15:28] over 2,500 companies offering salary and equity, both contract and full-time, just so many
[00:15:34] opportunities there. Make sure you use the special link, Hired.com slash developer T,
[00:15:40] which will actually double your signing bonus if you do end up getting a job through Hired.
[00:15:45] Don’t forget that Hired also gives out a referral bonus if you refer somebody else,
[00:15:50] so refer them to Hired.com slash developer T. Thank you so much for listening to today’s
[00:15:55] episode, and until next time, enjoy your tea.