My Digital Garden

SE Radio 656 Ivett Ördög on Rewrite Versus Refactor

SE Radio 656: Ivett Ördög on Rewrite Versus Refactor (developers, )

rw-book-cover

Metadata

Highlights

  • Emergent Complexity and Legacy Code
    • Emergent systems in software development become complex and hard to maintain over time.
    • Keeping code clean is expensive, leading many successful companies to have legacy codebases. Transcript: Ivett Ördög I think that one of the core issues with software development is that we tend to have these emergent systems. And as we develop them over time, they get so complex that we lose track of it and it becomes really hard to maintain. And there are a lot of ways we can avoid that. The problem is that those ways are expensive. And I think this is the controversial part where I'm saying that, yes, you can actually keep a system clean enough that you can always move fast. But that effort of keeping the code base clean is a non-zero effort, which is too expensive for small companies, which leads to the consequence of almost every single successful company Having a code base that is considered legacy or considered something that most engineers don't really like touching. Yeah, (Time 0:00:57)
  • Legacy PHP Codebase
    • A PHP codebase, started by juniors without oversight, became hard to maintain despite later tests.
    • Refactoring couldn't fix the fundamentally flawed import process, requiring a rewrite. Transcript: Sam Taggart Still comfortable working in it. Yeah. So can you dive into that a little bit? Can you give some examples of some code bases that had tests, but were hard to maintain? Yeah. Ivett Ördög So the codebase that we struggled with was a PHP legacy codebase. And part of the reason it was really hard to work with is because it was started by a bunch of junior engineers without any adult oversight. So they basically ended up creating this really hard to maintain code base where logic was intermixed with templating and with database interactions and everything. And over time, we started adding tests to it. But honestly, like when you have that level of complexity just up, even adding those tests can only help you so far, right? You still need to refactor a lot. And sometimes even if you do refactor, you might end up with like a system that is logically insufficient in the sense of, so the specific example I want to give is an import process that We had. And that import process was meant to process a CSV file and then move all the data from the CSV file into the database. Unfortunately, the way this was implemented is to move everything field by field, not even line by line. Like every single field update was a separate SQL query with lots of round trips to the database. And solving that issue is a bit more than refactoring, right? (Time 0:02:40)
  • Frontend vs Backend Refactoring
    • A system's backend was easy to refactor despite lacking tests, thanks to a dashboard.
    • The frontend, rushed due to deadlines, was difficult to work with. Transcript: Sam Taggart You also mentioned that you've encountered some code that did not have tests, but was easy to refactor. What made that easy to refactor? Ivett Ördög So one system that was fairly easy to refactor, actually, it was a system that had a backend and a frontend. And interestingly, the frontend was horrible and really hard to work with because it was just really quickly. It was actually my own system. I wrote for a few days because I had a deadline coming up. So I just rushed it all together. So the frontend was really hard to work with, but the backend was actually fairly clean and also didn't have any tests. And the reason it was really easy to work with backend was because even though it didn't have tests, I kind of had a dashboard as part of the frontend that showed everything. So when I reloaded that page, I immediately would tell if every single part of the system is working because that single page was kind of a test. Of course, it required me to know what to expect on that page, right? (Time 0:05:10)
  • Technical Debt vs. Financial Debt
    • Technical debt can be eliminated by deleting unused code, unlike financial debt.
    • Startups can strategically use technical debt to validate ideas faster. Transcript: Sam Taggart Another term that gets thrown around is technical debt. How does legacy code relate the term technical debt? Ivett Ördög That's a really interesting concept. And I think some people don't like this term, because it kind of implies that like has this parallel with financial debt and businesses are very happy to go into debt, right? That's all we have with investments. Investments are about going into debt. So business people are usually very comfortable with that concept. And because of that, it becomes a conscious decision if we want to take on debt, right? And I think a lot of engineers don't like that because that means that they can be pushed to take on debt, which they might not want to be pushed into. At the same time, I think it's still a really valid concept. And actually, it's even better than financial debt because think about the worst case scenario, which is actually the typical case scenario for a startup. You start building something and either works or it flops. You might have a project that seems like a good idea on paper. You build it, you ship it, and then no one uses it. Which one would you rather have? Financial debt or technical debt? Because financial debt, you still have to pay. The technical debt, that's really easy to pay at this point because you can just delete the code, right? (Time 0:06:18)
  • Managing Technical Debt
    • Be smart about technical debt and make calculated decisions.
    • Unintentional technical debt can lead to bankruptcy. Transcript: Sam Taggart Point where I can validate my idea. Do you find that some teams unintentionally take on technical debt? Is that a thing? I think it is a thing. Ivett Ördög And I think that what I would definitely advocate for is being smart about technical debt, right? You don't want to take it on unintentionally. You want to make a calculated decision when you're taking on technical debt. You need to be aware that you can run into a situation where you bankrupt yourself because of technical debt. So a minute ago, I talked about being able to delete the code and then the technical debt is gone. That's true. But at the same time, if your product is successful, then you have a different problem. (Time 0:08:10)
  • Rewrite vs. Refactor
    • Rewrite means discarding all code and starting anew; refactoring modifies structure without changing behavior.
    • Classic refactoring involves small, continuous steps with a working system at each stage. Transcript: Sam Taggart Great. So let's move into the rewrite versus refactor debate, and maybe we'll revisit that graph again. Can you define rewrite and refactor and talk about the difference between the two approaches? Ivett Ördög Rewrite would be something where you just throw away all of the code and you start over from zero. And refactor would imply that you change the system incrementally with just modifying the structure without changing the behavior. And basically in a classic setting or this classic definition of refactor implies that you're doing it in so small steps and every step of the way you have a working system. So that's something that you do continuously to clean your code base. Where it becomes interesting is that often people talk about bigger factors, where you need to change a bunch of things together in order to get to a more sustainable design. And how do you make sure that you don't just start doing that refactor, do parts of it, and then have to end up living with a hybrid situation. So when I talk about big refactors, I talk about situations where doing part of the refactoring job might actually temporarily make things worse. (Time 0:16:18)
  • Partial Rewrites
    • Consider partial rewrites, focusing on the most painful parts of the system.
    • Avoid large-scale rewrites or refactors unless absolutely necessary. Transcript: Sam Taggart All right, let's go back to that previous question. How do you know when you've ended up at the point where you don't have a choice, but you have to do some large scale refactoring or rewriting? What are the signs? What can we look for? Ivett Ördög Okay, for me, some examples that I can give. One example was this import that I previously mentioned. There was no option of refactoring because the logic of how we did the import was fundamentally fluid. You can't refactor it because that wouldn't change the behavior. We actually needed to change the underlying behavior of the system. And then refactoring is out of the question. Another very typical case of you can't do a refactor is when the platform you are building on is not suitable anymore. (Time 0:19:13)
  • Key Factors for Successful Rewrites/Refactors
    • Focus on delivering customer value and incremental progress in large-scale refactors/rewrites.
    • Ensure the project provides tangible user benefits or enables new capabilities. Transcript: Sam Taggart What other factors should organizations consider when deciding between rewrite and refactor? Ivett Ördög The way I would rephrase the question is, what are the fundamentally required features of a large-scale refactor or rewrite? Because I feel like that in general, you want to stay on the small scale refactor side. But when it becomes obvious that the system is not your friend here, and you are slowing down, I think that most of the time when you consider something like this rewrite or big refactor Thing, it usually has to do with a very specific business need that we have. And when you do that, I think there are two very important things to consider. The first thing to consider is how can I make sure that this project is delivering customer value, something that the user can also feel. This might be something like enabling a new feature that wouldn't be possible with the existing system, or making sure that more customers can be reached because we are opening up a New market, or maybe the only thing that the user notices is the system is more responsive or easier to use. But in the end, one of the two important things that I usually ask teams when they consider a rewrite is, how is this rewrite going to contribute to customer value? The other thing that is important to consider is, can we do this incrementally? Can we make sure that it's not an all or nothing effort? We don't want to be in a situation where we start a rewrite and then we have to stop it. And then suddenly we have a half finished product and we never get to release it, right? So can we do this rewrite in a way that parts of the rewrite are already used and enjoyed by customers before we finish? (Time 0:21:24)
  • Selling the Project to Management
    • Focus on business value when proposing a rewrite/refactor, treating it as an implementation detail.
    • Share the decision with leaders, considering their technical understanding and the risks involved. Transcript: Sam Taggart Guess, yes, it's all about risk. Speaking of business value, how do you convince management that you're at that point where something needs to be rewritten or refactored? And how do you sell that rewriting or refactoring to management? Ivett Ördög That's an interesting question. This discussion is very much based on the talk that I have. And the title there is, how do you sell big refactor or rewrite? Here is the interesting point. You might not need to. It might not be the right approach to try and come in this business. What's a much better approach is thinking about, okay, what is the value the business needs right now? And how can I deliver that value while improving on my systems architecture? And if you come at it from this direction, then you don't really have to convince the business about the refractory. You are convincing the business that the thing that they want you to build can be built the way you are planning to build. And depending on your specific situation, you might be in a situation where you don't have to share that you are going to do a rewrite as part of this. And in some situations, it might make more sense to share this information. It also depends on how technical your leaders are, right? So I would say there is a lot of nuance to when to actually even share this information. But even if you share, the point is to make sure that you focus on the business value that is being delivered and only treat the rewrite as an implementation data. (Time 0:34:20)