On today’s show we talk about refactoring. As most of us know, refactoring can be a very important part of tidying code and making it more useable in the future. But for a few reasons it is not always the highest priority on a project, which can lead to the process being neglected. We get into what the process looks like, parts that are enjoyable and also reiterate the value of the action. Ideally we would all work in spaces where refactoring was given its due attention, but if we do not, how can we go about emphasizing its necessity? Listen in to hear all our thoughts on the matter!
Key Points From This Episode:
- A definition of refactoring.
- Red green refactoring and its problems.
- The teams’ favorite codes to refactor.
- The fun and difficulty of naming code functions.
- Switching from refactoring code to work to refactoring it work better.
- How to realistically implement appropriate refactoring in your team.
- Using failures to emphasize the importance of the refactoring process.
- Some refactoring gone wild stories from the team.
- Refactoring teach and learns.
- And much more!
Transcript for Episode 50. Refactoring
[0:00:01.6] MN: Hello and welcome to The Rabbit Hole, the definitive developer’s podcast in fantabulous Chelsea, Manhattan. I’m your host, Michael Nunez. Our co-host today —
[0:00:10.4] DA: Dave Anderson.
[0:00:12.9] MN: And our producer —
[0:00:12.7] WJ: William Jeffries.
[0:00:14.1] MN: And today, we will be talking about refactoring. We'll get in to what is refactoring, we'll have a definition for it, how you can get buy in from the job that you're currently working in to be able to refactor and we'll share our horror stories about refactoring in general.
[00:00:35] DA: Yeah, how does refactoring makes you feel?
[00:00:38] MN: I like it; I enjoy refactoring when I know the code that I am working in is to move the code base forward. If I know I'm doing that and I refactor, then yes. It feels good like being a good scout like cleaning up and keeping thing tidy.
[00:00:54] WJ: I think it depends on the type of refactoring that you're doing like if you are adding test coverage to someone else's in touch of code that's sucks.
[00:01:01] MN: Oh, yeah, definitely that's not the refactoring I was talking about.
[00:01:04] WJ: Yeah.
[00:01:06] MN: But then once you have the test coverage -
[00:01:07] WJ: Then you're going to clean it up, that's amazing.
[00:01:07] MN: Yeah, it's like being - I mean we talked about this so many times in the show in part but we never had a full episode in refactoring. Well, what it's like eight different episodes that we found, that we mentioned refactoring?
[00:01:19] WJ: That I can remember.
[00:01:21] MN: Yeah, there's like TDD, there's like planning all sorts of different places where we cover refactoring mentioned.
[00:01:26] DA: Yeah, red, green, refactoring and TDD. I had a plan to do refactoring and Tech TED and test coverage and -
[00:01:33] MN: Legacy code and all sorts of stuff.
[00:01:36] DA: It all comes back to it just the simple act of refactoring which I guess we haven't defined yet. Did you want to give us out William?
[00:01:42] WJ: To me refactoring is changing the way code operates without changing what code does. Usually it's done in order to make the code more maintainable or more readable although it can also be done to make it more performant.
[00:01:56] MN: Is that Martin Fowler, we're talking her right now.
[00:02:00] WJ: I don't know what Martin Fowler is out hopefully it is in line.
[00:02:03] MN: No, no it's excite it's very similar to what you just said. I think the definition that I just googled is 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. Dude do you like Martin Fowler.
[00:02:21] DA: Is that from The Definitive Refactoring book.
[00:02:21] MN: Yeah, I believe so.
[00:02:23] DA: Yeah, The Definitive Refactoring book, The Definitive Refactoring book, it's just called refactoring. Yeah it's all -
[00:02:28] MN: It's a pretty amazing read. I would suggest any and every one to take a stab at it.
[00:02:34] WJ: The Definitive Refactor's Guide to Software Development.
[00:02:38] DA: Exactly. The guide to not writing features, just moving code around.
[00:02:44] MN: So, we can talk about refactoring and theory and how it actually plays out, one thing Dave you mentioned earlier red green refactors in theory the way you want to refactor.
[00:02:55] DA: Right.
[00:02:55] MN: In code base just like being able to write a test, it fails you make a pass, you figure out ways to make it more efficient.
[00:03:03] DA: Right, but I guess if you just have a static code base that you're approaching to do a refactor then you're not going to have the red part, these are not writing a feature in a two way fashion it's just going to be green and then you're going to write a code and it's still going to be green, so it's a little more boring I guess.
[00:03:20] WJ: Yeah, if you are perfect. If you can be never write anything wrong.
[00:03:26] DA: Exactly, just me.
[00:03:33] WJ: Just you Dave.
[00:03:36] MN: Just you. If you did a red, green refactor that is in theory you would want to refactor.
[00:03:41] WJ: Yeah, when I refactor I usually goes red and stays red for a while and goes green very briefly.
[00:03:49] MN: Yeah, maybe you got to refactor and make it at less lines of code, make it more readable.
[00:03:52] WJ: Eventually goes back to green.
[00:03:54] DA: Yeah, you got to keep green. Yeah, it can be easy to get lost in it sometimes too especially if you're like taking off a big bite of a refactor like if you have a hundred line method and you're like alright one shot let's do this.
[00:04:09] MN: Ooh, let's go.
[00:04:09] WJ: I'm definitely doing it wrong you're supposed to stay at green as long as possible. It should be in the red for the shortest period time possible.
[00:04:16] DA: Yeah, I like to use watch with Jest or really any testing framework has some helper library or function that will let you run the test automatically when you change to a file. I think that's really super helpful when doing a refactoring because then you can make the silliest level of change and then just keep on tapping over to your test, and be like “Okay I'm good still.”
[00:04:43] WJ: There is a plugin, I don't know if it's still being maintained called Growl that I use back. I don't know several years ago that would create a like a Mac OS pop up that will let you know when your test is red or green.
[00:04:58] DA: I remember that, the thing, yeah.
[00:04:59] WJ: Seeing it at as a tab.
[00:05:02] DA: But will it let you know when it changed? Or just all of them.
[00:05:05] WJ: I think when you save the file.
[00:05:07] DA: Actually I found out that there is such a feature in Jest the other today. If you just pass the flags that is just to notify then it will send a native OS X notification to you. When it finishes running it so if you have watch with notify then it's just going to be popping up every time you save the file which is pretty cool actually.
[00:05:29] MN: Oh that is awesome.
[00:05:30] DA: But then you have a little bubble like just there all the time.
[00:05:34] MN: Yeah, telling you you're a failure, all the time.
[00:05:37] WJ: You see that failing, you're failing right now.
[00:05:42] MN: Dave whose perfect, that is still like -
[00:05:46] DA: Yeah, it could -
[00:05:46] MN: Humility. In theory, red green refactor is a possibility but reality is there is often times where you deliver some feature and knowing that you may have to pay some tech debt down in the future to do some refactoring later like what other features will touch the file you're currently implementing. So in reality you may need to write tickets for these features.
[00:06:22] DA: Yeah, yeah, I mean it's definitely nice when you can do refactor as you're going, you know sometimes, like you mentioned, the reality of it is that sometimes you need to take a moment and evaluate where the most benefit is to me those changes and sometimes writing a story and prioritizing it, against things that are more valuable pieces of work or more like featured driven pieces of work that you could be working on instead.
[00:06:51] MN: Yeah, so I mean trying to do as much as possible, you want to refactor as much as possible, if you have to move it later down the road, you can create a ticket and have your team prioritize where it belongs and then continue to work on refactor later.
[00:07:10] DA: Yeah, and if you want to hear more about it you listen to Episode 19. Tech TED.
[00:07:14] MN: Ooh, nice awesome.
[00:07:15] DA: Deep cut.
[00:07:17] MN:Yeah, I think we were having a conversation before in life about getting buy in. Right like refactoring is cool as developers because we want to make sure that our codes are perfect all the time. Dave writes the code perfectly all the time, so this may not apply to him.
You know I love to hear more about this.
[00:07:41] DA: So, what is your favorite code smell to factor away?
[00:07:44] MN: I am personally not a fan of if's and nested if's statements.
[00:07:52] WJ: Oh, my god I was going to say the same thing.
[00:07:52] MN: Yeah, sorry, sorry bro, I spoke first. I spoke first. I saw this in a code base that I was working where there were just if and then else if and then else if and I have mentioned “Okay I need to, we need to figure out a way to early return this function so that we don't have any of this if's all the way down the road.”
[00:08:14] DA: Oh, yes this is Chapter 9, Simplifying Conditional Expressions, section 37 placing this unconditional of guard clauses from the holy refactoring book.
[00:08:26] MN: Oh, man, yeah that's great, you killed them.
[00:08:27] WJ: I can't believe you did that for memory Dave, no wonder you write code perfectly.
[00:08:32] DA: Of course.
[00:08:34] MN: Yeah, that's definitely one of my favorite codes most to get rid of just like, I don't know too many if statements that's weird.
[00:08:41] DA: Yeah, too many if's.
[00:08:44] WJ: No checking that's another really satisfying one to get rid of.
[00:08:48] DA: What do you mean by that? Is that to check that, that thing is not no?
[00:08:52] WJ: Whenever in the code if someone is checking to see if something is null, that's always an interesting challenge to figure out how to make it so that they don't need to do that like guarding at the edges of your application rather than allowing the null values to permeate the code base.
[00:09:10] DA: Yeah, yeah, that's always an argument I hear for having more type checking with something like Flow, with no values.
[00:09:16] MN: Well, say that for the teacher to learn. We can save that for the teach and learn aspect.
[00:09:23] DA: For me personally I get a lot of satisfaction of decomposing long methods in to like smaller things.
[00:09:29] WJ: Oh, yeah me too.
[00:09:31] DA: And just finding really nice names for all of the things so it's like the same as in documented.
[00:09:36] WJ: Naming stuff, oh my god.
[00:09:36] DA: Get rid of your comments. Get out of your comments, I got a method.
[00:09:41] MN: Get out of your comments.
[00:09:42] WJ: I will straight up hit a thesaurus looking for the perfect method name.
[00:09:48] DA: Is there program called thesaurus?
[00:09:52] WJ: There should be.
[00:09:52] DA: I need to write that eBook because I'm horrible but maybe I can't because I'm horrible naming functions and variables. I love pairing because I hope that my pair can name things better than I can. I leave it out to you guys to do the refactoring of naming and functions and so.
[00:10:13] WJ: Having a pair when you're trying to come up with method names is actually great because it can be a sense check and be like “No, that no.”
[00:10:22] DA: Right, so what are you doing?
[00:10:23] WJ: You think that makes sense but that is just you.
[00:10:27] DA: And sometimes it should not be a really good name like everything becomes a service or a controller or something else. Yeah, it can feel validated to come up with it with a friend.
[00:10:40] WJ: Yeah, turn it in to a micro service.
[00:10:41] DA: Yeah, that's a refactor in itself turning it while it is in micro service, a massive one by all type in itself. What was that red, green refactor in to micro service?
[00:10:55] MN: Yeah, that is part two of this sooner, going all the way.
[00:10:57] DA: Yeah, so how do you kind of like work passed - I think often like the first instinct is if its working don't change it right that's often the first feedback that you get when it's like this piece of code is kind of gross and if we refactor it would be better to work with.
[00:11:23] MN: Yeah, I mean that's kind of why you want to refactor it so that you can take that grossness and make it nicer, so that other people can then want to work on it, I don't know.
[00:11:30] WJ: How do you get yourself in the mindset - like how do you change your perspective from oh I just got in to working to, “Oh I need to get it working better?”
[00:11:40] DA: Yeah, yeah, I mean it's like one way or when I think about it is like it's really easy to keep on standing on patterns that are already there in the code base like I find myself just repeating things like when I'm in the red statement trying to get to green like I'm just going to repeat the patterns that are already there.
[00:12:00] WJ: Copy pasta strikes again.
[00:12:02] DA: Yeah, I'm just doing what feels comfortable and not trying to rock the boat too much until I get to the future complete state but then if you never take the time to actually go back and clean it up then -
[00:12:13] WJ: And once you hit feature complete then you really want to stop.
[00:12:18] DA: Right, that's when it's time for a beer.
[00:12:23] MN: Oh, yeah even if it's 10:30 in the morning.
[00:12:26] WJ: I think pairs are particularly helpful for this because your pair can have that critical thinking hat on and be looking for ways to improve the code while you're still writing it and then they have a direction to take it as soon as you're done with the method.
[00:12:40] DA: Right, they'll be like biting their tongue while you're writing code the whole time.
[00:12:42] WJ: I got it from somewhere else you got to keep quiet.
[00:12:43] MN: It's because they're doing this. I like to stop him. That is all for pair programming.
[00:12:51] WJ: It's like live Tweeting, assholes putting cons everywhere.
[00:12:56] MN: What are you doing?
[00:12:58] DA: Haven't had you have heard of cons.
[00:13:01] MN: What are you doing? I have a ton of index cards like cons, cons, cons, cons, cons letter. I might just make a way to run. All the cons. Cool so you want to refactor it's a thing that you want to do, the thing that maybe a couple of individuals in your team want to do but then reality strikes. Yup, again. Yeah, these are requirements that require people to push out features and struck down deadline and there's no time I'm sure every single individual listening right now has heard there's no time we need to get this out now. I mean that sends sure is down my spine because its post traumatic distress disorder, what I am hearing right now.
[00:13:50] DA: Right. It's like reading a finished project just like oh my gosh it's too real.
[00:13:56] MN: So you want to get buy in from your team, what are some ways in reality we can do to get buy in for a refactor?
[00:14:06] WJ: I think one thing that you can do is just do it, just refactor while you're writing your code. Do red, green refactor, don't ask for permission, you are professional and it is your job to do software development well and that’s how you do it well. You don't need permission from anybody to do that.
[00:14:24] DA: Yeah, and I think also like when I've gone like I'm billing, “Okay, I need to refactor something in order to do my job well.” It's often been like driving towards like some business value like I need to work on those feature on this page but it's very difficult to reason about what this code is doing so I might just take a moment and refactor it and trying to imagine how it might work better or like the easier to think about.
[00:14:51] WJ: Make the change easy and make the easy change. Like if there is a feature that you have to implement and you have to touch terrible section in the code base. Clean that section up and then go to add to feature and it will be much, much easier and if anybody questions you, you can say I needed to do it in order to ship this feature which is true. Anybody having more devilish tactics that they've used?
[00:15:12] DA: Yeah, so I've definitely been in a place where like I've seen out there might be a problem that could happen but like we're just pushing ahead and you know you try to bring it up and well like, “Well we don't have really time right now,” and then you could push through and like go rogue and refactor or address the technical debt on your own time like put in extra hours but that leads to burnout and so like sometimes it might be fine just to like let the situation to come to a head and like you know just see it coming and just be like “Okay I accept these buildings are going to crumble down on top of me.”
[00:15:52] MN: Right, you see the train coming, you look at it arms wide open I accept my fate, crash and burn.
[00:16:00] WJ: Sometimes business needs to lose some money that's you know how you get people's attention.
[00:16:07] MN: Yeah, I mean it's definitely like one way that translates to efficiency very well like there's a cost value to the refactor that was necessary and be like, “Oh you see we lost money because we could've made that particular feature more efficient.”
[00:16:25] WJ: Obviously, you should go to people and tell them when there's going to be a problem and you know there's going to be a problem but there will come a day when people will ignore you and then the site will go down and they will lose a bunch of money and as soon as that happens you have an amazing opportunity to go in and put a dollar value on refactoring and say finally I can compare this to that feature that you want that you think is going to make us more money.
[00:16:48] DA: Right.
[00:16:47] WJ: “Here is where we make sure that never happens again, okay. We want three sprints.”
[00:16:52] DA: Yeah, that is a really powerful and I think we talked about this like in the tech dev, episode 2 it's like, “Yes there is a monetary cost to this crumby code that we have to deal with like it slows us down and you're paying us hourly.” You know, when there's an outage there's a very direct cost but you know when more people are feeling the pain then, you know, that's when you'll get more action.
[00:17:20] MN: Awesome, so we now just spoke how about how we can actually add dollar cost value to refactoring which is really, really great. Let's go around and share some refactoring stories that we have or as we call the early refactoring gone wild.
[00:17:38] WJ: I mean I have definitely got a little bit too deep in to a refactor to the point where it's touched half the files in the code base and I realized that there is no way I will ever merge it back in and I have to throw it away and start over.
[00:18:31] WJ: Have you ever introduced a bug while refactoring?
[00:18:33] DA: Yeah, definitely. Especially if it was like not a perfect test coverage or like those kind of like edges around the application that you're not really testing through units. Yeah, like links between two pages or something like that like moving files around, that's a good example of like how something might break when you're refactoring.
[00:18:54] MN: I would make the suggestion that if in the event you introduced a bug while refactoring definitely write a test to catch that bug and then fix it so that doesn't happen again if the event, someone else refactors that piece of code.
[00:19:08] WJ: Good advice.
[00:19:07] MN: When does a refactoring go well?
[00:19:11] DA: I guess that's the question.
[00:19:12] WJ: When you have good test coverage.
[00:19:15] MN: Absolutely, I think you just go and rip things apart, make changes, did it break anything? Did it break anything?
[00:19:21] WJ: I don't even think about it I just turn the switch and we're done.
[00:19:23] MN: Yup.
[00:19:25] DA: Yeah, even then there maybe that one thing that breaks, that each need to like test four or like fix forward.
[00:19:32] WJ: Maybe open a browser just -
[00:19:38] DA: Right, the browser should be open.
[00:19:40] WJ: Have you ever had any positive experience? with refactoring and improving performance.
[00:19:43] DA: Yeah, definitely. Actually, that kind of a satisfying thing there as well if you have the test coverage like what we're talking about earlier and you have the tooling in place, which if you're ready for the front end is super easy I can talk like quite a bit about crumped up tools but it's more interesting if you actually see them in action like in a blog post form or something but there's some really cool stuff that you can see where the bottle necks are kind of get back to basic algorithm questions and try make some performance and get rid of and plus one things and loops and whatever other crazy things -
[00:20:24] WJ: Nexus one queries man, they're everywhere.
[00:20:26] DA: Yeah, that too.
[00:20:31] MN: I think the one satisfying refactoring that I've done recently was working with Lodash, I did't know that using Lodash dot, like the chain function in Lodash. Imports all of Lodash because Lodash allows you to use any Lodash function. So I thought it would just allow when you run chain you can call the things that you want and continue to chain on them, but since Lodash doesn't know what you're going to chain it will just import all of it. So I have to refactor chain to just using this specific Lodash functions that I want and just importing those things means that it doesn't import all of the other ones which is pretty cool for your belt. I mean it was like, “Oh, snap don't use chain like if I'm not going to import all of it just use the specifics ones that I want and then that was like amazing.”
And, that was something that you can't really test with coverage and tooling as much you've liked and you notice your bill files it gets so much more reduced.
[00:21:57] MN: 50 KBs a lot. It adds up.
[00:21:59] WJ: I mean if you're going to use like one function out of it, yeah.
[00:22:02] DA: Left pad, it’s all I needed.
[00:22:06] WJ: Yeah, just go in the library, copy and paste the one function you need and you're done, you never to worry about upgrading it underneath you.
[00:22:14] DA: Ten p.m. copy, paste.
[00:22:18] MN: Awesome does anybody have any teach and learns?
[00:23:10] DA: Yes, you can have like another assurance of build time that you didn't mess anything up.
[00:23:57] WJ: It's either crystal or opal or some other gem.
[00:24:02] MN: That's all the gem stone.
[00:24:03] DA: I know that Mets are ones like static typing and Ruby 3.0 like in the core which I mean, yeah, everybody is doing it all the cool kids.
[00:24:11] MN: All the cool kids statically typing, statically typing away. Cool, that calls for the end of the episode. I like to thank our co-host, Dave thanks for coming on down.
[00:24:22] DA: Yeah, thanks man.
[00:24:24] MN: And our producer William always a pleasure.
[00:24:26] WJ: Happy to do it.
[00:24:27] MN: I'm Michael Nunez, feel free to hit us up at twitter.com/radiofreerabbit and if you haven't please give us a five star rating on iTunes and subscribe. This is The Rabbit Hole, we'll see you next time.
Links and Resources: