Live Long and Refactor by Sana Javed

This video features Sana Javed at DjangoCon US 2017 in Spokane, Washington, USA.

Live Long and Refactor by Sana Javed
0:28:11
Published September 7, 2017
470 views

DjangoCon US 2017 - Live Long and Refactor by Sana Javed

Refactoring major components of a live application with many users can be daunting. The stakes are even higher when the users are paying for your product. This talk covers how to approach building and incrementally deploying a complex refactor. Using a case study, I will walk through what makes major refactors so challenging, what you should avoid, and what can make them easier in the future.

This talk was presented at: https://2017.djangocon.us/talks/live-long-and-refactor/

LINKS:
Follow Sana Javed 👇
On Twitter: https://twitter.com/sanacodes
Official homepage: https://www.github.com/sanajaved7

Follow DjangCon US 👇
https://twitter.com/djangocon

Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/

Summary

Sana Javed argues that a large, incremental refactor is often safer than a full rewrite for a profitable application with paying users, because a rewrite creates a moving gap between the old and new systems and can lose undocumented behaviours. Drawing on a year-long refactor of National Journal’s authentication and authorization systems, she recommends first stabilising the application, ensuring deployments and data are reproducible, adding basic smoke tests, and identifying the root cause rather than treating individual symptoms. She advocates working in small vertical slices of user value, repeatedly refactoring, deploying, and validating each slice, while keeping old and new code separate, resisting scope creep, and postponing premature deduplication until the transition is complete.

Key takeaways

  • A full rewrite can struggle to catch up because the existing application continues changing while version two is being built.
  • Before refactoring, make the application reproducible, keep configuration and migrations in version control, back up the database, and establish basic smoke tests.
  • Trace bugs and user-visible problems to their shared root cause instead of refactoring isolated symptoms.
  • Refactor toward complete user-facing capabilities, deploying and manually validating each slice rather than waiting months for a large release.
  • During a transition, some duplication is useful because it keeps the old and new implementations clearly separated and easier to remove.
  • Record tempting side issues for later and hold the scope line so detours do not extend the refactor indefinitely.

Summarised automatically from the transcript.

Chapters

  1. 0:00 Introduction and the Krenim Imperium A Star Trek Voyager story introduces the risks of attempting a full rewrite.
  2. 3:18 Refactoring Versus Rewriting The talk defines refactoring as incremental architectural improvement and contrasts it with rebuilding an application from scratch.
  3. 4:06 The Case for Refactoring The speaker explains why a rewrite can fail to catch up with an evolving production application and may discard undocumented user needs.
  4. 7:59 When to Begin a Large-Scale Refactor Signs of refactoring need include brittle code, technical debt, poor maintainability, and fear of unintended consequences.
  5. 9:33 Application Stabilization The first practical step is making the application reproducible, recoverable, and consistent across environments.
  6. 11:10 Test Scaffolding Basic smoke tests provide support and protection before deeper changes begin.
  7. 12:41 Finding the Root Cause The speaker describes tracing user-facing bugs back to the fundamental structure that needs refactoring.
  8. 14:16 The Refactor–Deploy–Validate Cycle Incremental deployments and human validation reduce risk while keeping work centered on user value.
  9. 19:44 Clean Code and Scope Control The talk covers temporary duplication, maintainable design, and resisting distracting detours during the refactor.
  10. 23:38 Refactoring Resources and Recap Recommended books and methods are followed by a summary of the talk’s core practices.
  11. 25:48 Questions Audience questions address when a rewrite is justified and how to stay focused during a refactor.

Transcript

5,458 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:14

Speaker 1: All right, um hi everybody. I am uh really excited and a little bit nervous to talk about refactoring today, but hopefully it will be fun. Um so let me see. Is this working? Yeah. So I wanted to start um a little bit by talking about uh these two particular episodes that show up um in Star Trek Voyager uh in the middle I think or right at the beginning of season four. And if you're not familiar with Voyager, um it's with Captain Janeway, her crew, and they uh kind of accidentally end up 65,000 light years away from from Earth, like really um off course. And um part of their, you know, the entire um series kind of uh details their way

1:00

Speaker 1: Back home, and one uh in these two particular episodes, they find that if they take this particular path, they can shave off a couple years of their journey back to Earth. And And uh they do a little bit of research. It looks like the you know the folks that kind of inhabit this part of space are generally non-confrontational, they think it's gonna be okay, um, but you know, it wouldn't be called year of health. There wasn't kind of like a plot twist there and it turns out that they actually run into this uh species called the crenim that are actually highly confrontational and um you know they don't want to allow a Voyager to be able to go through this part of of space. And I think the the interesting thing about this and especially about the Crenum is that their

1:45

Speaker 1: sort of m uh method of of of war of choice is that they've actually figured out a way to rewrite history and change the entire timeline to prevent their enemies from ever actually existing. And I think what um what's interesting about that, even more than just that that's a really cool thing that they can do, is that um they always get it wrong. So whenever they they are trying to get the this crenum imperium as they call it back to this particular st state of of power, um but whenever they do these calculations they think that they've accounted for everything, every distortion that they know of, they feel really confident, they change the timeline, and then something always goes wrong. They never actually get it right.

2:31

Speaker 1: And I think I think at one point in between the two episodes, actually, Captain Jane when her crew figure out that they can create this like temporal shield to protect themselves from the Krenim. That also throws their calculations off. that actually puts their empire like way further behind than they anticipate. And I think the the lesson in there for us as software developers is that sometimes when we try to do entire rewrites, there might be things that we don't account for that could lead to some unintended consequences. So I think that's if you get a chance to watch them, I think they're on on Hulu or Netflix. And they're super interesting episodes. So, yeah, so just to kind of get on the same page about what is an actual refactor versus a full-scale rewrite.

3:18

Speaker 1: Michael Fowler, one of the most kind of prominent engineers who thinks about refactoring and clean code a lot, has his sort of definition But it it really boils down to sort of like small architectural changes to the code that aren't changing anything that your end user can really tell, but it's putting the code base in a or whatever feature that you're refactoring in a better shape for maintainability, making it easier to test, making it easier to adapt in the future. But you know this and when I talk about a large scale refactor today, what I'm referring to is a series of these smaller refactors to smaller features in the code base to, you know, under kind of some broader goal. like umbrella. And this contrasts obviously with a full-scale rewrite, which is really building every single feature from scratch,

4:06

Speaker 1: starting all over and not focusing on just one set of features. or one feature which would be a refactor. So when and why then I guess is a refactor a maybe a better option for you rather than a full-scale rewrite. I mean, if you're the Krenim, probably don't do it, but uh there's there's a couple of reasons. And I think um some of the most important things to think about when you're comparing a refactor to an entire rewrite is that when you have the existing version of your application and your code base, this is after you know you've got a lot of users, you've got a lot of features, there's been a lot of time dedicated to this version of the application. When you are starting that rewrite, you've got a pretty tremendous gap between version one point oh and version two

4:52

Speaker 1: point z, right? And that um you know for most businesses or organizations, that code base is still going to continue to evolve. You've got users, you've got maybe new features, maybe bug fixes that you need to make the entire time while you know a set of developers are maybe tasked with building out version 2. 0. And uh Bob Martin in his Clean Code series uh says that this is sort of a classic example of the Achilles and Tortoise paradox that Zeno talked about. many many years ago and what's happening is that because there's that gap and because version one point oh is sort of evolving continuously it's very difficult for the folks that are working on the two point oh version that of that application to ever actually catch up. So what you're left with effectively

5:39

Speaker 1: is the question when if ever is version 2. 0 of the application going to be done. And I think another great point that he makes of referring to Bob Martin is that if you're working with a code base that's difficult to maintain, it has a lot of unintended consequences when you change something over here. here in the application and it breaks something somewhere else, you're you probably don't have really great test coverage or you might have outdated test. And one thing that makes closing that gap um even harder on top of that is that you probably don't have a requirements document. So for the developers who are going to be working on that rewrite, they have to spend quite a bit of time in just understanding what are the requirements for this application? And that if they're buried in the existing code base, it takes time to kind of extract those out of there.

6:27

Speaker 1: So that also kind of furthers that gap and makes It even harder to you know kind of get to a point where version 2. 0 is actually going to be complete. Um other uh other things that are important to think about too is that even if If you have a requirements document, even if you know exactly what are the components that you need to rewrite, you know, we have to think about the emergent properties that are in the code base. So if there's ways that your users are using the application That you as a developer or as a you know product owner might not even be aware of, that's something to seriously take into consideration because if those are features that you're um you're paying users really rely on for their jobs or their um you know whatever that they use for your application for if they depend on those and they're paying you for that product

7:13

Speaker 1: a full scale rewrite might like actually accidentally get rid of those and that could be a pretty bad user experience for those folks. And I think the other thing to note too is that depending on the size of your team, sometimes it's just too expensive to say our entire dev team or a big portion of it is gonna work on this full-scale rewrite, especially if we don't know when that's gonna be complete, when you know you've still got users that you have to respond to to kind of on a day-to-day uh basis. Great. So when should we do a large-scale refactor? I've talked about this kind of of hinted at it a little bit, but you know, sometimes as developers we have to rapidly build out an application uh or a product, get it out to market, and that's not Easy but easier to do

7:59

Speaker 1: than also thinking simultaneously about concepts like technical debt, maintainability, test coverage, you know, is this code in the best um possible shape for for being able to adapt and change over time. And you know sometimes what we end up with is an application that's you know both functional functional and profitable. But a code base that's very brittle, it's very difficult for the developers to work in. So when you have a scenario like that, it might make sense to think about a refactor that would help put the code code base in a more maintainable uh form. And so um I think what else I'm gonna say. Yeah, so you know going back to the point earlier, when you've got an application that has a lot of users, you don't want to risk you know messing anything up and losing them and you know they keep the lights on at the end of the day

8:46

Speaker 1: that's another thing uh that risk is something you have to take really seriously um and yeah when when the developer are not not just scared but a little bit apprehensive about making changes because they always have unintended fallout. That's probably another indicator that maybe you need to consider a refactor Yeah, so if you're at that point where you know you're maybe going to consider a refactor, what are some of the steps, especially if it's gonna be something fundamental to the application that you Work on how do you actually begin that process? At National Journal for the past year, we have been refactoring our entire user authentication and authorization process So I'm just going to sort of highlight the process that we follow, the things that have worked for us over the past year, and hopefully if that's something that you're considering too, it's

9:33

Speaker 1: it's helpful. Right. So one of the first things um that we did was to really focus on uh stabilizing the application. And what I mean by that is can you um confidently answer questions that if your application were to go down, if you, you know, all your servers were to completely be wiped, you had nothing, would you be able to bring your application back up? It seems like depending on where your particular applications are Maybe you're in a great position on that anyway. Um but for us we really had to make sure of to be able to answer that question things like can you deploy your application across different environments or does it only work on the production servers that you currently have? Things like is everything in version control? Sometimes if you have a really chaotic

10:19

Speaker 1: code base and that needs to get fixed right away, there can be a habit of just SSHing into that server, making that hotfix, restarting the application because it's so urgent you have to You can't, you know, follow like a pull request process or something. So things like that can have a really big impact because if the version of your code base that's on production looks very different from What's on staging or what's local, that can, you know, before you change a single line of code, you really want to make sure that, you know, everything is in version control. Um some of this stuff might seem obvious. but are your are your secret keys, your you know API, uh API keys, passwords, are all of those in environment variables? Um if you're working on a Django application, are your data Database migrations in version control? Do you have database backups that are generated regularly so that you're not connecting to product the to the production database by accident?

11:10

Speaker 1: you know, getting dummy data live in front of paying users. That's really precursory work, but it's important to kind of make sure all your ducks are in a row before you change even uh a a single line of code. The next thing that's also another sort of preliminary step is to, depending again on your application, but if you have really outdated tests or you don't have any tests, it makes sense to kind of have some really basic test scaffolding. In DC where National Journal is based, we had the C Capitol building under repairs for quite some time. And one of the first things that we did or that they did during that process was to really build out this construction scaffolding to give a little bit of more support and and coverage for the repairs that were to come.

11:56

Speaker 1: And I think you can think about your your code base in a l in a little bit of a similar sense, right? The uh basic tests and what I mean by that is do I get a 200 response? Does that page load really, really simple test can kind of prevent you from having unintended downtime, especially if you have a code base that's a little bit chaotic and a little bit volatile? And the thing is if, again, depending on the team that you're working on, if uh there's not really a culture of testing, if there's not um really, if the code base is not in any kind of shape to even be broad , under test coverage that can require a lot of work up front but that's something that as you continue to you know write the test for the refactored uh you'll sort of see the return on that information investment pretty quickly and and pretty um

12:41

Speaker 1: extensively as well. So I I would definitely recommend that. Great. So once you are, you know, you've got some kind of uh a little bit more of your application in a stable place, you've got some basic test scaffolding, the the next thing that I recommend doing is really trying to to understand what element of the application actually has to get refactored. It's easy sometimes to focus on the ways that the problems manifest, especially for the end users in terms of terms of bugs or things that you work on, but I really recommend tracing the problems back down to the root as the root cause as much as possible. It's usually going to go back to something pretty fundamental in the app application, it's probably gonna be scary and that means that you're probably on the right track.

13:29

Speaker 1: You know, for us we had a variety of different little edge cases of, you know, something wrong with the user's permission, not being able to access the content um that they were supposed to, uh a weird bug with like a little blip where they were supposed to be able to log in, but you know something else happened. And for us, we sort of trace that back down to, well, where are these problems really originating from? What's the root cause here? And it turned out to be it was just the way that our entire auth uh authentication and authorization were process were structured. Oh a really great resource to help guide you on that is the Makado method. Really great book. I think the authors are are up there. I would recommend that. It was super helpful uh for me this this past year. Great. So now um I want to dive a little bit more into this

14:16

Speaker 1: entire Refactor uh process. So there's a couple of points here that I wanted to make. The first is that when you uh the cycle is broken up into three kind of core components. The first is the refactor, which includes you know writing the test and writing the code for the actual component the next is deploying that pretty quickly and then the third is sort of validating that human uh validation that everything is sort of working correctly especially as your test uh your test uh uh suite is still evolving. And I think the point that I really wanted to emphasize here is that you want to refactor to user value and and not to systems. And so I I love this analogy of the cake because it really shows

15:02

Speaker 1: that when we eat cake, we don't really start with like the base layer and then the second layer and then eat like the frosting and then the top layer. We really take a slice and when you think about that in terms of user value, it's it was super helpful for us to sort of sort of structure work, you know, in this example it's a user should be able to pay with a credit card or a user should be able to pay uh with PayPal or be able to pay manually. And what that means is when you're working on or when you're going through one version of that or the first phase of that cycle, you're doing all the work that it would require for the user to be able to log in, right? And then you would deploy that component you would make sure that that's working and then you would move to okay now the user should be able to log out and then you do all the work that's related to that and you know those are those are fairly simple but you know once you get into other components

15:50

Speaker 1: Like, okay, on a permission-based system, a user with a certain permission should be able to access, you know, this particular uh type of content. Without it, they shouldn't be able to access it. It really helps you know when that part when that cycle is done, like okay, I can confirm that I've got tests verifying this, a human has also verified this, this piece is deployed, let's move on to the next component. And overall following this cycle really helps mitigate the risk. that comes even with a refactor. You don't want to really be in the place where you worked on something for six, seven, eight months and then you're finally deploying it and then to find out it doesn't work. or there's something really basic, deploying really frequently and to user value helps really mitigate uh that risk. And you know, who doesn't like cake?

16:36

Speaker 1: So that's a good way to think about it. And this is like just a quick screenshot of like how we were sort of structuring our tickets in GitHub is what we use for us. And so just saying, okay, with this permission, a user should be be able to access this. This is going to be all the work that's kind of tied to that. RPM sometimes tests you know features and stuff for us. So it makes it really clear for everybody to be on the same page of when this component is done and it's it's live, what should be, you know, how can we know that it's it's complete? And then talking a little bit more about that refactor phase. I think it's really important to and and the vertical stories sort of force you to do that, but it's really important to understand um, you know, what is the acceptance criteria for that feature.

17:23

Speaker 1: Something like logging logging out obviously that's really obvious a user's got an email's got a password they should be able to log in but if you've got a feature that maybe somebody worked on a while ago and there's a little bit less in situ institutional knowledge around it, it really makes sure uh it's really helpful to make sure everybody is on the same page and they say, well, when they go to this page and they click this button, they should be able to download this CSV. This CSV should have these components components, getting that um that criteria kind of upfront and and really clear among all the stakeholders is super helpful. And that's it's helpful because once you have that It's really clear how you need to sort of write your test. Something kind of throughout this process that's really important is that you've got current users using your application and you're trying to make the experience for them better.

18:08

Speaker 1: and you're trying to make the experience for the developers who work on the code base, you know, a little bit better too. And so the one of the first things for me in this process was making sure that I had test for that existing feature. Making sure that as I'm changing the code around, as I'm you know building out something new, I'm not unintentionally or I'm not intentionally or un yeah, unintentionally causing problems to the existing users. So tests for the current uh features super important. The next piece on that is writing tests for the new system. Hopefully those tests will look very similar. So when Once you have that first test, you're kind of, they're gonna be a little bit more higher level. You don't want them to be for super specific private methods, but really kind of tying into the uh the user. functionality and um and then I would write the code for uh you know the refactored code

18:57

Speaker 1: and then you know deploy. One thing that really helped my thinking on this process was Was uh Martin Fowler's blog post on the Strangler application pattern. It's it's a little bit different because he's talking about that in reference to uh a completely separate application overtaking an existing one but I think the concept is still applicable to you know one feature that's gonna strangle an existing one kind of out of existence and um I really would recommend uh reading it it uh it It was really helpful for me. And you know , Captain Crook and Gorn fighting when you know your code doesn't want to get strangled is always something funny to think about. Great. And so on this part about

19:44

Speaker 1: writing clean, maintainable code, I wanted to um talk a little bit about this too because you know when you're following something like the Strangler application pattern what you're gonna have are sort of two versions of uh code for the same feature and as developers one of our um Kind of biggest instincts is to make sure that our code is dry, that we're not repeating ourselves. But you have to sort of put that instinct on hold a little bit at this process because um one drying up your code uh too quickly in this process can lead to really tight coupling. And what you don't want and what you want at the end of the process is a really clear division between this was the code for the current system, this is the code for the new system. new one, I know exactly what needs to get ripped out when the refactor is over. If you've got um you know a

20:29

Speaker 1: a a method that's sort of responding to both systems it can be really hard to kind of untangle which piece was using was being used by which one. Um it'll just kinda save you a lot of headache uh at at the end. So not saying that focusing on not repeating yourself is not important, but at this stage in the process it might be good to just say we want a little bit of duplication here so we know what we're what we're actually need to get rid of. And yeah, and I think it's I think it's really important to just uh slow down and really solve the task at hand. A lot of times the reason why we are doing a refactor is because we need to make our code more maintainable or we had to get an application or a product out to market really quickly. And if that's the case, this is really your time to put a little bit of um you know

21:15

Speaker 1: polish on the code, make sure that everything from really basic stuff stuff to good environment variables, doc strings, uh not environment variables, sorry, uh variable names, uh doc strings are are in place, but also a little bit more advanced stuff like are there hidden clusters? classes here that can be split up? Can we introduce an interface that will make this code a little bit easier to use? I think those are those are super important. And yeah, I think where where you didn't have the opportunity in the beginning to really focus on maintainability, this is really your opportunity to do that. And I think another another really difficult thing to do is to hold the line on scope. And what I mean by that is, you know, when you're in the code base and you see something that has kind of been a bug for a long time and you're like, I can just take a quick

22:04

Speaker 1: detour and and fix this and then come back to you know to what I was doing or it's just gonna take me five minutes, let me just hammer it out. Those detours as um as distracting as they can be and and tempting to kind of hold off on them, they actually will end up anchoring and and uh adding up over time to how long the refactor is going to take. And when you're doing something like an entire over overhaul of an authentication or authorization system, you really want to make sure that you're keeping your eyes on the prize and really getting the refactor done as as quickly as possible too. So holding a line on scope and not getting distracted by all the kind of millions of things that you just wish you had like a second to fix and then you you know but you kind of still take a detour. And you know really the end goal is that the code base is gonna be in a much better position

22:49

Speaker 1: for you to be able to make those changes at the end of the day. So you know keeping that in mind, just sort of focusing um on that. Okay. Yeah. Great. Um and this is not to this is not to say that writing clean, maintainable code is is easy. It's actually very hard. It's a process. It's one that um takes a lot of time. It takes a lot of thought. And when you're used to you know things kind of on fire and a little bit of chaos. and and working really quickly to like you know hammer out features it can be weird to to sort of take take your time and um you know and and work on it well but I would say use the tools that are at your disposal there's uh engineers and developers who've been working on and thinking about this type of stuff for for decades.

23:38

Speaker 1: Some of my favorites are Uncle Bob, uh Bob Martin. Um if you've ever watched his videos, he is a really hilarious person and he wears a lot of different costumes, dresses up as Fock, as Captain Kirk. He's really great resource. Michael Feathers has a fantastic book, Working with Legacy Code. And he covers everything from, you know, I well like it's it's sort of like a resource book where I want to change something or I don't know how to bring this um under test coverage, how do I start? That's another great resource. And And Martin Fowler's refactoring book is also really fantastic. I also mentioned the Makado Method book earlier. Those are really great. Yeah, so So just to recap, um if your application is profitable, if it's got a lot of users, but it's really difficult as a developer to work on or to maintain, or changing something in one place causes a problem.

24:30

Speaker 1: other places and you're playing whack-a-mole, you might really want to consider a refactor to make your code base a little bit more maintainable. And when you start the refactor, you want to ensure that your app Application is uh stable by making sure it's reproducible, that it's got at the bare minimum basic you know smoke test. And when you're thinking about what needs to get refactored, you really want to not just focus on the way that the different issues are manifesting for the end users or the bugs that you're seeing maybe in your logging system, but really looking at what is the root cause of all these different problems and really kind of seeing the the forest through the trees. And yeah, try to follow the the refactor deploy cycle as closely as possible to both mitigate risk but then to also

25:15

Speaker 1: you know know when that um that component of the feature is done and try to do it to user to user feature rather than the system and remember that sort of like cake analogy. And yeah, you're going to be maintaining two versions of the code base until you're actually done and not focusing on dry too early. Which should be it. Yeah. And so with that go forth and and refactor. Thanks.

25:48

Speaker 2: What point would you consider that the you know say your your code base is so terrible that it'd be worth doing the full rewrite rather than the refactor?

25:56

Speaker 1: I don't think it's a matter of how terrible terrible the code base is, I think it's a matter of whether or not you've got paying users that depend on your application. You know, for us, we serve a lot of different government agencies, organizations. organizations, associations and doing a full rewrite and the different risks that come with it are just were just not feasible. And so even though we were having a number of different problems kind of crop up, it It made sense for us to say, we're gonna refactor. We know that the problems are sort of stemming from this one place. We're gonna allocate all of our time to refactoring that. Um and I think Bob Martin makes a good point in um in one of his videos and he says you just have to sort of face where the problem is stemming from because um if you do the rewrite you might actually end up making some of those same mistakes that were

26:41

Speaker 1: existing in the first code base too. And I thought that was that was a really great point, especially if you're under that kind of time constraint and that pressure to get that second version out just as quickly.

26:53

Speaker 3: The uh draw to take those detours, even if it's just uh fifteen minutes or a half hour or so, it's easy to say

27:01

Speaker 1: yeah

27:02

Speaker 3: don't do it. Do you can you offer any advice as to how best to um to maintain focus?

27:08

Speaker 1: Yeah I think um one of the things that's that's been my go-to is that if I notice something to at least flag it for RPMs or create an incoming tissue so uh tissue create an incoming issue so that I know that at some point I'll be able to kind of go back and be like yes I wanted to circle back and and focus on this so not giving too much brain power to to the the things that I'm like oh that's a bug I want to fix it um and then I think uh what I like about the vertical stories approach right that cakes Is that I know exactly the piece that I have to work on. So if it is okay, a user should be able to sign up for this newsletter, I know that's that's the piece that I'm working on. And once that's done, Maybe if I have time or whatever later on I can come back to that piece that I sort of saw was problematic, but kind of just flagging it and kind of putting a pin in it for myself to come back to later is

27:55

Speaker 1: been my go-to.

Questions this talk answers

What’s the difference between a refactor and a full rewrite?

A refactor makes small architectural changes without changing what users experience, improving maintainability, testing, and future adaptability. A rewrite rebuilds every feature from scratch, starting over with the application.

Discussed at 3:18

Why is refactoring often safer than rewriting an existing application?

A rewrite creates a large gap between the current and new systems while the current system continues to evolve, making it difficult for the new version to catch up. It can also lose undocumented user behaviors, repeat old mistakes, consume substantial team capacity, and leave users unsupported.

Discussed at 4:06

When should you consider a large-scale refactor?

Consider one when the application is functional and profitable but the code is brittle, difficult to maintain, or risky to change. Developers’ apprehension about unintended fallout is another strong signal.

Discussed at 7:59

How do you prepare an application before starting a major refactor?

First stabilize it: make sure it can be reproduced and redeployed, all code and migrations are version-controlled, secrets are managed safely, and reliable database backups exist. Add basic smoke-test scaffolding as needed so changes do not cause unnoticed downtime.

Discussed at 9:33

How do you identify what part of an application needs to be refactored?

Trace user-facing bugs and edge cases back to their root cause instead of addressing each symptom separately. The underlying problem is often a fundamental part of the application’s structure, even if that area is difficult or intimidating to change.

Discussed at 12:41

How should you structure the refactor-deploy-validation cycle?

For each component, write the tests and code, deploy it quickly, and then validate it with a person as well as the evolving test suite. Repeating this cycle reduces risk and makes it clear when each piece is complete.

Discussed at 14:16

How do you refactor toward user value instead of system layers?

Work in vertical slices based on user capabilities, such as logging in, logging out, or accessing permission-controlled content, rather than completing an entire technical layer first. Each slice should be tested, human-validated, and deployed before moving to the next one.

Discussed at 15:02

What tests should you write during a refactor?

Begin by testing existing behavior so current users are protected, then add tests for the new system. Keep the tests focused at a user-functionality level rather than tying them too closely to private implementation details.

Discussed at 18:08

Should you keep code DRY while replacing one system with another?

Not immediately. Some duplication can make the old and new implementations easier to distinguish and remove later; sharing code too early can create tight coupling and make the final cleanup harder.

Discussed at 19:44

How do you keep a large refactor from expanding in scope?

Stay focused on the current user story and resist detours to fix unrelated bugs or polish other areas. Flag those issues for later, while using clearly defined vertical stories to maintain focus and finish the refactor sooner.

Discussed at 21:04

When is a full rewrite preferable to a refactor?

The deciding factor is not simply how bad the code is, but whether paying users depend on it and whether the risks of a rewrite are feasible for the organization. A rewrite can also reproduce the same design mistakes as the original system, so a targeted refactor is often more practical.

Discussed at 25:56

How can developers avoid getting distracted by bugs during a refactor?

Record each tempting detour as an issue or task so it is not forgotten, then return to the defined vertical story you are working on. This lets you preserve focus without losing track of worthwhile follow-up work.

Discussed at 27:08

Presenters

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from DjangoCon US