Nicolas Carlo talks with host Sam Taggart about Nicolas’s recent book, Legacy Code First Aid Kit. They start by defining legacy code and the general issues that developers face when dealing with it. Nicolas describes some of the tools in his book and provides some examples of where he has found them useful. The episode also touches briefly on the role of AI and some other tools Nicolas has discovered since writing the book.
SE Radio Episodes
- 363 – Jonathan Boccara on Understanding Legacy Code
- 295 – Michael Feathers on Legacy Code
- 587 – M. Scott Ford on Managing Dependency Freshness
- 595 – Llewelyn Falco on Approval Testing
- Your Code as a Crime Scene (second edition)
- Software Design X-Rays
Transcript brought to you by IEEE Software magazine and IEEE Computer Society. This transcript was automatically generated. To suggest improvements in the text, please contact [email protected] and include the episode number.
Sam Taggart 00:00:53 For our Software Engineering Radio, this is Sam Taggart. I’m here today with Nicholas Carlo and we’re going to talk about his book Legacy Code First Aid Kit. Nicholas is a freelance web developer who loves building communities and maintainable software. He organizes the Software Crafters meetups in Montreal, Canada and shares tips on how to work with legacy code on his blog understanding legacycode.com. So welcome Nicholas.
Nicolas Carlo 00:01:17 Hi Sam. I’m happy to be here with you.
Sam Taggart 00:01:20 Great. So the first question is, your book is called Legacy Code First Aid Kit. How do you define legacy code?
Nicolas Carlo 00:01:28 That’s a good question. So I think most people, well most people will define legacy code as some old code, which is not my definition. A popular definition of legacy code is also Michael Feathersí definition, which is any code that is not tested and it’s a great definition in most cases because in general you are working with code that is not tested. I have a slightly different one because I want to capture some nuances. My definition is legacy code is valuable code that you are afraid to change, which may be because it’s not tested, but I’ve seen some tested code that would still level as legacy. And also, I like to emphasize first on the fact that if you’re dealing with legacy code, it means that you’re maintaining a code that is impacting people, it’s using production, otherwise you could just throw it away and do over and it’s generally not a scenario. So it’s a valuable code in most companies there are successful, you will have legacy code that also pays for the salary. So yeah, I like to think about legacy code as, something you must maintain. It may be a challenge and painful we’ll talk about that, but also it can really have a lot of impact on actual people.
Sam Taggart 00:02:47 Yeah, you kind of answered my next question, which was how do you decide when code is worth saving and refactoring what should be thrown away? But there is another part to that question which is, are there times when you should take legacy code and maybe it’s okay to just slap some duct tape on it and keep it running as opposed to doing a real refactoring and really fixing it up and modernizing it?
Nicolas Carlo 00:03:08 Yes, a lot of the answers will be it depends, but I’m going to try to explain what it depends on and what to do. For rewrite versus refactor, yeah in general, rewrite is a bad idea. It has been detailed in many posts, but the only moment where rewriting the thing is a good idea is either you are building something new so it’s more of a like a new product and there is a talk from DHH, creator of Ruby on Rails who was like, okay, but rewrites are fine, et cetera. And when you dig into it you realize, okay, he’s talking about building a whole new product based on what you learn on the first product. But in this case a rewrite is fine. The second scenario is when the rewrite is very small that it wouldn’t be worth iterative approach. And that’s the trick for large systems is to make a rewrite small enough.
Nicolas Carlo 00:04:03 So you take a small chunk of, for example, a monolith, you take a small chunk that you identify and your scope is to rewrite that part and then you have strategies in place to ship to production this new maybe microservice along the legacy code base and have all of that working in production together. So in a sense you could consider it’s a rewrite, but it’s a rewrite of a tiny chunk and that’s how you should address legacy code bases. When is it not worth doing any kind of iterative improvement? I don’t know. I would say you probably need to be careful when you do not have, tests in place. For instance, about the changes you are making. The first thing you will need to do when you rewrite a legacy code base is put in place safety nets. So automated tests, lost documentation, lost knowledge, try to recover that, monitoring also logs all of these, if they are not in place, you should start by putting them in place before you make meaningful changes. Otherwise you risk wrecking a lot of stuff without even realizing it. So that will be the scenario where before trying to refactor the whole thing, I will just make duct tape minimal changes on it.
Sam Taggart 00:05:25 Yeah, I remember seeing an interesting post where somebody said something about if you’re going to rewrite something, reimagine it. So like take kind of like the DHH quote where you take what you learned, and you just write something new that does whatever it is you would do now. And I think that could be worth it too. I mean I think part of the problem seems to be risk refactoring always seems like a less risky option in my mind.
Nicolas Carlo 00:05:48 Yes. Also risk and we underestimate the rewrite project because it’s like with AI. AI can help working with legacy code basis, but as a support tool, if you hope to just use AI to refactor for example, a piece of code you do not understand, the problem will be, you cannot evaluate if that’s correct. And that’s the same for rewrite because how can you tell if the new rewrite actually does what the old system does? And there will be a lot of surprises because all the context you have lost, it’ll be revealed to you and it’s better to have it revealed progressively in small chunks rather than with a big bang scope. We had that story. So I work and live from, Quebec in Canada and early this year the part of the government that is responsible for the cars and all this. So they have a system, legacy system you can imagine, and they went to modernize it and they announced, hey, we’re going to shut down the services for like three, four days and we’ll be back up and it’s going to be whole new and magical.
Nicolas Carlo 00:07:00 Yeah, you can anticipate what happened. It was a disaster. I think that happened in February or something like this and it created big issues until, August and still today you can see some cars driving it. They do not have their license plates because of all the delays that happened because of this. And they even estimated the cost of that failed modernization project that cost them multiple millions of dollars because they had to pay people to work extra hours to compensate for the new system not working. So when you talk about a failure and a budget wise, like not only the budget but also the reputation like people were pissed off. Yeah. Rewrite was not a good option here.
Sam Taggart 00:07:48 Yeah. So my next question is sometimes I run into situations where management is reluctant to invest in refactoring. Have you ever run into that and why do you think that is?
Nicolas Carlo 00:07:59 Yes, yes, that’s, I think it’s interesting because it’s one of the main complaints that developers will have, which is we don’t have time or like management won’t, hello us people just want to ship new features. And I’ve seen that. Yes, the thing is, there are two reasons for that in my experience. The first one is the failure of making a business case for what we’re doing. Like when we’re talking about refactoring and all this, it’s all technical stuff and we use a lot of technical jargon. You cannot expect the people driving the business to just understand what that means and how that is helpful? For them it looks like it’s working, maybe not. They don’t see the value in how it connects to the business, but it does, it does because if you do nothing you will have a lot of trouble with the business and the developers can anticipate that.
Nicolas Carlo 00:08:54 They can see it coming. It’s just that they fail to communicate the importance of the work with business works. So there are a bunch of things you can do in that area, which in general goes to try to explain, try to connect the problem with what it’ll mean for the business now or later. And if you have an organization that has SLAs and SLOs for example, that’s you have it, you have your connection here. If it impacts the SLAs, it’ll impact your client, it’ll impact your business, you can see that. If you don’t have that it could be interesting to put them in place. But you can also look at the cost of fixing the bugs. How many bugs are you fixing every week, every month? How much does that cost in terms of salaries? You can look at the opportunity cost.
Nicolas Carlo 00:09:42 There are a lot of things to look into and you have to think business like what that means in terms of money, reputation, client, et cetera, that technical implication. So that’s the first one. And the second, I would say it’s the legacy culture. We talk about legacy code but in general, like always the problem is more often with the people. Noting that the people are bad, but they operate in a way that doesn’t help fixing the situation. For example, it’s very common that the only thing that gets visible in a company, but in tech in general, it’s the makers, the explorers, the new features, the new stuff, always new, new, new. And that’s the only thing we talk about. If that’s more maybe an advice for technical leaders, tech leads, CTOs, et cetera. But if you’re in a position where you can change that culture, it’ll be the biggest impact you can have because if you start making visible the work that is essential to keep the system afloat, then more people will do it.
Nicolas Carlo 00:10:49 For example, if the end of your sprint demos, you save 10 minutes for mentioning the people who are upgrading dependencies. Yeah, just that example for instance, if you can try to have a score of how out of date your system is and plot that on over time with the graph and then mention the people who are helping move in the right direction, you’ll see more people interested in doing that. If you never mention it, no one will just upgrade dependencies until they have to. So changing the culture is something you can do if you are in a more, leadership position. But it’s important to help your engineers make the system more maintainable.
Sam Taggart 00:11:31 Yeah, it’s interesting you mentioned dependency management. I just interviewed Scott not that long ago on Freshly. We’ll throw that in the show notes. The other cultural thing that I’ve noticed is sometimes people are afraid to rewrite code. They kind of view it as a waste. Like oh we wrote this and then we learn more about the problem and now we have to go back and rewrite it. And they think, oh that’s a waste. My opinion tends to be, well no, we learned what we need so let’s go build what we need. But I don’t know if you’ve run into that or not.
Nicolas Carlo 00:11:59 Yes, I remember I read recently Kill It with Fire from, Marianne Belloti and she addresses this. She said you need to build the wrong thing the correct way. Implying that for instance, microservices are never the thing to build first because you do not know how your system will evolve if it will evolve. I mean I worked on a system on startups, and we threw away half of the code base a few months later. So you’re taking on complexity. Microservices are harder to manage, especially if you only have a few engineers for a gain that you do not have and that is hypothetical. But if you go with the monolith through routes, of course at some point when you scale it won’t work and you will need to rewrite it. And then that’s when people are like, oh that code base, like it was too naive who wrote that?
Nicolas Carlo 00:12:56 Oh I did, like of course past decisions they had less context about the changes you need to make today. So I also try not to predict the future too hard. It’s something you can get better at when you are familiar with the domain you are working with. Of course you can anticipate where things are going to go and if you’re good you can make future maintenance easier. But I try not to make things too complicated upfront, just the thing that will work now and for the next move and do not be afraid of revisiting decisions and rewriting a part of it or redoing it. It’s also part of the job in a sense it’s successful because it means that now you have the scalability problem you didn’t have before, which is good news because before you wanted to go from zero to one and now you need to go from one to a hundred. And that’s a different thing to do if you try to take too much complexity at first, like scalability and, and all of that over engineering, you will actually go slower and if you’re at that zero to one scale you won’t be able to try so many things. So yeah, I agree with you. It’s not a failure to rewrite something in the future. It’s actually a good sign.
Sam Taggart 00:14:11 Great. The other cultural thing I see is sometimes organizations save up refactorings and do them all in one big push and I’m kind of curious about your opinions on that.
Nicolas Carlo 00:14:22 Oh yes. Well it depends first of course like I mentioned the culture before and refactoring as you go, as you implement new features is something that also should be part of a healthy maintainable culture. Basically what I like to do personally is to refactor something as I’m tackling a new feature because I know what the next move’s going to be. So the first thing I do is to make the change easier. So that’s refactoring and then the change is easier and now we make the change and all of that is part of developing the future. So that’s great because I do a lot of refactoring without saying to management that I’m refactoring that’s how the sausage is made, and they cannot tell the difference. But I can tell the difference at the end with the quality of the system. Now a lot of refactorings can be made like that.
Nicolas Carlo 00:15:19 However I’ve seen sometimes problems that will need more, like we mentioned rewrite before and the monolith for instance. Okay, at some point we may need to do the extraction in the microservice, et cetera. There may be more work in this case it may make sense to have a dedicated piece of it. I will still try to, well in general I like to tie any refactoring or technical work to a business outcome because we don’t do that just for the sake of it. It’s because we want to make a change for the business at some point. And this refactoring this task enables us to do that. So it’ll be part of a project. But in another scenario that is more frequent is people already have this pile of technical depth and now they are starting to think about modernizing. And now you may have to make some efforts like okay we need to spend, we had at a previous company I worked with that we had what it called sustainability week. Like okay a week every quarter the engineers will have the time to tackle on the project that didn’t get much love for example upgrading dependencies, et cetera. I think it’s less ideal than having that part of the culture of like do that every day as you go. But when you arrive in a new company or the culture is not here, it’s better than doing nothing and just wait.
Sam Taggart 00:16:47 Yeah, my question would be is how sacred was that week and how often did that week get canceled because there were other priorities?
Nicolas Carlo 00:16:54 It’s a great question. No definitely it happened to be moved or to have one canceled, but the CTO was not bad as trying to make it sacred because he managed to get the, use that week for product to think about the roadmap, the vision of this, which it’s clever. Again ideally I would rather prefer to have not just the product thinking about the product and the engineers coding, but to have everyone part of that discussion. You have engineers who know the system and how the system works, include them in the discussion of what the system should do next and it will be better. But again, if you are working with a legacy system and a legacy culture, you need to start somewhere.
Sam Taggart 00:17:45 Yeah, that’s are some great thoughts. So talking about the book a little bit more, how would you compare your book to previous books like Michael Feather’s books or Martin Fowler’s refactoring book?
Nicolas Carlo 00:17:57 Yeah, comparing to Michael Feather’s book is tough. I would always recommend reading Michael Feather’s book first because it’s a reference and also his book, he really shares the mindset of how you should approach legacy code in general. There are a few concrete examples, but he also talks a lot about how you approach that kind of code. And this is something that I don’t necessarily tackle in my book. For instance, my book will be more, you are currently stuck with a project, and you are in the trenches, you need a way out, you need some techniques. And what I did was to collect the techniques I used most frequently and to detail what they are, why they work and how to apply them in the book. And so that resulted in a 200 pages e-book with 14 techniques. But that’s more a toolbox to use when you are in the field versus Michael Featherís is more how you should approach legacy systems in general.
Nicolas Carlo 00:19:03 And I think you should have both. It depends. You mentioned Martin Fowlerís refactoring book. It’s probably looking more like mine in the sense of, it’s a catalog of refactoring recipes. So it’s a book you will go back to. It’s not a book you will read cover to cover and then put on the side, it’s a book you will get back to whenever you need to do something, and you look for the refactory move and you apply the steps. It’s a bit more like my kit. And in my book, I also detail the few refactoring moves that I use the most when it comes to legacy code. So there is a bit of overlap, but I would say of course if you wanted to become a better engineer in general Martin Fowlerís book, it’s a catalog of 50 plus refactoring moves. It’s a huge reference. So I would also recommend this one.
Sam Taggart 00:20:03 Yeah, it almost feels like refactor is like one small subset of all the tools that you have. Because there’s a bunch of other tools in there too that are not necessarily refactorings.
Nicolas Carlo 00:20:11 Yes, I would recommend another book actually because we’re talking about books and inspiration. So we mentioned Michael Feathers, we mentioned Martin Fowler of course two big sources of inspiration but also Adam Tornhill. So that person, if you don’t know him, wrote a book that is called Your Code as a Crime Scene that is the most popular one. And there has been a second edition in 2023 earlier this year. But he also wrote another book called Software Design X-Rays , which is an iteration of your code as a crime scene. I would recommend one or the other like Your Code as a Crime Scene or Software Design X-rays because it’s the only book that I know that addresses one technique that is tremendously useful for a legacy code basis. And this is behavioral analysis. So the idea behind behavioral analysis is to approach your code as a crime scene.
Nicolas Carlo 00:21:14 You don’t know what happened here, you have lost a lot of the context and the knowledge because developers are gone, there is no test, there are no docs, et cetera. But you try to grab what happened from what you see. And with software you have a ton of information in version control metadata like GIT. With GIT you can know who touched what and when at least and with that information that is in general people don’t think about this. But when you use that to combine with your other static analysis tool like the usual ones, you combine them together and that gives you a lot of things you can do like finding which files to prioritize in terms of, refactorings based on the quality but also how frequently you change these files. You can also identify the part of the code base that some of the developers are experts in because you can see who contributed the most to which part, which can also be useful for offboarding.
Nicolas Carlo 00:22:22 If you have a developer leaving the company, it could be helpful to know, okay, which part of the code base do you know a lot about and many other things you can infer. So I detail the hotspot analysis for instance, that is in my book is coming from that. It’s something I use frequently when I arrive on the system and I want to prioritize what to do, especially on large legacy systems. People are overwhelmed with everything they could clean up and that gives you a manageable subset of okay, you should start here and that’s a plan you can present to management because now you can talk about return on investment. Like if we spend that amount of time on this file, we will have the biggest return on investment for refactoring efforts. Like they understand that a little bit more. It sounds like a plan. So I would recommend this.
Sam Taggart 00:23:13 Very good. That was actually one of my questions later. So, your book lists 14 or 15 tools and techniques. Are all of them language-agnostic?
Nicolas Carlo 00:24:19 Is it more functional, is it more object oriented? Is it procedural? So what I try to capture is what to do and what you are looking for. Like you want to invert the side effect like extract the business logic from the side effect. That’s what you want to do, and I will show you how you do that with the object-oriented code and with functional code. But then you have to adapt and there are techniques that apply. Yeah, regardless of the language. So the behavioral analysis, as long as you’re working with version control tooling, you will have that. In general it’s GIT. You could also have that with Mercurial if, and like if you end up on the system that is still using this, which we’re talking about legacy systems. So it can happen, but this will be relevant regardless of the language.
Nicolas Carlo 00:25:11 And one tip I can share by the way, when you are doing hotspot analysis, you need to combine the, so the frequency of the change, the churn with the code complexity and many languages has something to calculate the code complexity. But if your language doesn’t have, you can always use the count of lines of code for every file because well it has been proven that it’s not super accurate but the trend of lines of code tend to follow the trend of complexity. So, when you do not have any other tool, that’s a good first guess.
Sam Taggart 00:25:49 Yeah, I really like the hotspot analysis tool, but I find I don’t end up using it a lot mostly because a lot of the legacy systems I encounter are not actually in source code control. So that’s like the first step. So there is no history to go back and look. So hopefully in the future I’ll be able to use that a lot more. But also a thing you mentioned about doing examples in one language and kind have to extrapolate them to others, I mostly program in LabVIEW so I’m very used to doing that because there are very few books written in LabVIEW, most of them tend to be Java or C sharp or something. So next question, which of the tools in the book do you happen to end up using the most?
Nicolas Carlo 00:26:31 That’s a good question. Well the hotspot analysis, I use it a lot when I arrive on a project because like I’m doing consulting so when I arrive on a a new codebase I use data, as part of the tool, like I talk to a lot of people and I also use that to see if that confirms what I am understanding and also give me hints of about who to ask and stuff like this. But that’s situational. It’s not something I would use all the time when I’m coding, which is the case today, the techniques I resort to the most often are the ones above the like refactoring the code. So there are a couple of refactoring moves that I show. But yeah, inverting the dependency, like separating the business logic from the side effects is something I do all the time. And the automated refactorings, it’s interesting because I found that a lot of developers I’ve worked with, they don’t know what their editor can do for them.
Sam Taggart 00:28:56 Yeah, I imagine that will only get better with AI tools now. Have you noticed anything in that front. Does that show any promise or is it still in its infancy?
Nicolas Carlo 00:29:05 it’s a big 23 topic. Earlier this year I worked a lot, I was curious about this like what AI can do to work with legacy code and I found some promising stuff. For example, there are some tools that can help you understand what the piece of code is doing. I said earlier the difficult part is how can you assess that it’s correct or not? So you should not just take it for granted. But in my experience, it’s a good support, like it helps you grasp a few things much faster and if you use that combined with other techniques it can get you code much faster. I have seen actually some startups today are going on for the AI is going to write the test for you. I give a little hand here and my conclusion today is promising there are two main problems here.
Nicolas Carlo 00:29:59 The first one is how can you say that the tests are fine or if there is anyone any other tests missing when it’s generated automatically? That’s one difficult part. The second is the quality of the test. When the code is a bit complex and things are tangled together, you need tests that will allow you to refactor that code after. If you write test mocking everything and making everything super rigid, it’s going to be difficult for you to refactor the code after you have the test. So these are difficult but there are, I’ve had good success with using such a tool to find test cases that would have taken me a long time to realize like I don’t know this piece of code, I would like to write some test before I do anything with this. And having AI ingest that code and suggest test scenarios for me was actually very helpful.
Nicolas Carlo 00:30:54 It speeds me up. And the last piece that I’ve seen is using AI to refactor the code for you. So you give it legacy piece of code tangled spaghetti mess and you ask it, hey, refactor this, make it simpler and here well yeah sometimes it may get it right but I tried it on things where I had the test so I could tell whether or not it got it right. In general like I think most of the time it had at least one issue, one regression somewhere. And again the problem is when you do it for real you cannot, if you do not have your strong test suite before, you cannot tell. So I would not use that yet unless you have good tests. If you first have the test then I could use AI to refactor some code eventually. The second thing, and this is ongoing experiment, is combining both. Combining automated refactoring tools like the automated refactoring tool, we will parse the code into an AST, do value transformation to that tree and then generate code again AI will be generative.
Nicolas Carlo 00:32:10 The idea is, okay maybe we can have AI suggest refactoring moves and connect that with your editor who can do the refactoring moves safely. And that is interesting because I think AI can be really good at suggesting creative stuff, especially if you’re not an expert in refactoring and you haven’t read all the 50 plus refactoring from Martin Fowlerís catalog. So AI can do that for you, but you don’t risk it on AI hallucination to transform your code base. You lean on your editor that you can trust that knows the structure of your code across the project.
Sam Taggart 00:32:54 Yeah, that’s really interesting, sounds promising. So going back to the question of which tools you end up using most, I found one of the tools I end up using a lot almost unconsciously is the naming. Starting out with some name and like generally I’m okay at coming up with something close but usually I end up like just as I’m doing it I’m just constantly iterating on the name and I thought that was rather interesting.
Nicolas Carlo 00:33:19 Yes, this one was inspired by, Arlo Belshee. He wrote a series of Naming as a Process, is the name of the series of blog posts. And it’s interesting because the idea of–naming is hard. Most people will agree with that. It’s a very, very difficult problem to get names right and people try to get the name right at first try pretty much like we said earlier, like rewriting something feels like a failure et cetera. But the same with the name, actually no because you learn as you do and, the more you learn the more you can improve the names. And so that’s what Arlo is describing and that’s also what I picked because you can improve names progressively in a legacy code base.
Sam Taggart 00:34:02 Yeah. I also find naming leads you to refactorings. Like you end up naming something that’s like do A and B and C and you’re like oh well those are really three concrete things. Maybe we should extract some methods there or something. So my next questions is, which tools do you think are least familiar to developers?
Nicolas Carlo 00:34:21 For working with the legacy code? The tools they don’t know much about. Well in my experience behavioral analysis tools in general, like the thing I mentioned earlier with Adam Tornhill and all of that, every time I present it somewhere, people are discovering this concept. So it’s a powerful concept and yet it doesn’t get as much love. Every developer has heard about refactoring from Martin Fowler, probably about working effectively with the legacy code. But Adam Tornhill, that’s also why I wanted to mention him. So he wrote the books, he did a lot of study around that some open-source code and now he has a SaaS software code scene so it’s free for open-source projects. So you can try what it can do, but it’s, yeah you pay for it for a legacy project, for a private legacy project.
Nicolas Carlo 00:35:13 But I think it’s worth it because you get everything that I mentioned in one tool you can use on your software and this is something people don’t know and yet again when we’re talking about legacy system that are under version control, so sorry not your case, but if your system is under version control and it’s critical, it’s in production used by millions of people bringing like a lot of money but it’s all that needs to be improved, I would spend some budget on code scene to analyze and give you a lot of insights about what you can do, where you should start, see who knows what, where, who interacts with who does that align that the code structure aligns with your organization also, will you find coupling between two repositories in different languages that you are not aware of all of that. So behavioral analysis and could be seen as a tool are not very well known.
Sam Taggart 00:36:17 Yeah, I have a friend who refers to that as code archeology which is very interesting because you’re looking at all the artifacts in the repository. So I think partly because I had talked to you before I read the book that that was actually not new to me but one of the things that was fairly new to me was the Mikado method because the only time, I’ve ever heard of that was Manning I believe has a book about it. But that’s the only time I’d ever heard that mentioned. How did you stumble upon that, and can you talk a little bit about what the Mikado method is?
Nicolas Carlo 00:36:46 Yes, the Mikado method, it’s an interesting technique. I don’t use it all the time, but I resort to it when I have something to do that is unknown in terms of scope. So more frequent when the task to address is big or I am new to the project. So the idea is you want to achieve something, you write it down, it could be on a piece of paper, you write down your objective, I want to upgrade that dependency. Okay, that’s your target. Then you set a timer, you try to keep it short like 10 minutes, 15 maybe, but not, I would not advise to do more than 15 minutes and you will understand why. So you start the timer, you try to complete your task within that time box and what happens is you will fail of course because if you could do that within 10 minutes you wouldn’t think about doing the Mikado method in the first place.
Nicolas Carlo 00:37:44 So yeah, you fail, it’s normal, your timer rings and you have not completed what you wanted to do. You have maybe some works in progress or maybe you’d have nothing, and you just went and discovered a few things about the code. So when you are at that point you should stop, you should think about where you are, what have you discovered, are you blocked, what do you need? And you write it down on your paper, you try to find blockers for your main objective or maybe you are breaking down what you need to do into smaller parts. You write them down as nodes on your paper and you connect them to the main node, your main objective. Then you pick one of these new nodes. A subtask, if you will. You start your timer again and before you start over you get reset dash, dash hard everything.
Nicolas Carlo 00:38:38 If you really cannot resort to doing that, you should at least stash everything. The idea is that if you happen to change code in that time box, you need to revert that change because you need to start fresh from a fresh state on a smaller subtask and you repeat, you do that again, you may fail again like 10 minutes won’t be enough to do that subtask. So you do, you repeat, you write down what you found, you have a sub sub subtask eventually and at some point, you will be able to complete something within this time box. Maybe in two minutes you will be able to do that little change you wrote down and that’s a different process. So at this point you’re successfully making a change within 10 minutes. When you do so you can do a commit. So you will have small commits by design and cross it off your Mikado graph.
Nicolas Carlo 00:39:38 The Mikado graph is what you are ending up with on your piece of paper or you can use if you are using online tools, I suggest you go for a mind map tools because there are really convenient to draw these kinds of graphs. So you cross it over and then you pick something else that is low in the tree. The idea is that you start with the smaller tasks first that are requirements for doing the big ones. By doing the smaller ones you will finally be able to tackle the bigger one because all the blockers will have been addressed and now it’s trivial to make it done within 10 minutes. And so you really have two phases. The first one is you are discovering everything you need to do. It’s like you’re resolving the dependencies of your task that wasn’t known. And it’s good when you do the Mikado graph because you have a visual artifact of it.
Nicolas Carlo 00:40:36 you know that tonal effect when you start working on something and then you have a lot of change going on and you don’t know how far you are from the end, but you cannot revert back to the beginning, nothing is working et cetera. The Mikado graph is the solution for this. It’s you’re doing the same thing but the difference is as you move with this discipline, you have a clear view of everything that you need to do which you can discuss with the rest of your team because maybe you realize that the task is too big and you can split into smaller stuff and eventually you have a second phase which is okay now I’m resolving all of the issues until the end and that feels good because it’s basically you have a to-do list and you just follow it and cross everything you can get in the zone while doing this. It’s good for the brain. So yeah, in general I would use it. I told you when I’m not sure about the scope of what I’m trying to achieve and if I see someone in standup three days in a row saying I’m almost done, I know that okay that person next time we need to pair a little bit together so I will show them this technique because that’s a solution to I’m almost done every day without any concrete detail.
Sam Taggart 00:41:50 Yeah, it’s one of those things sometimes I set out to use it like I know the task is big or I know it’s going to touch a bunch of different pieces but sometimes I start on a task and I think it’s going to be a quick task and if after 10 or 15 minutes I’m like I’ve touched like three different modules now no I’ve got this other thing that I don’t know about. I’ve like okay, stop, wait, draw it out. And it really helps clarify things. I think I find it
Nicolas Carlo 00:42:13 Very useful, yes, but it’s also very difficult, like the part where people struggle the most, it’s the revert your changeís part and that’s why you should not do more than 10 or 15 minutes because if that’s 10 minutes of work, that’s fine, you can throw it away. But if you’ve been working for an hour, you do not want to throw everything away. And yet I think it’s a great practice to practice throwing away code. I did that on Kata but I did that on code like following the Mikado method. You do that in production code, you try something, it does not work, and you throw it away and you try again and usually when you try again it’s better.
Sam Taggart 00:42:51 Yeah, very true. So speaking of struggling out of the tools of the book, which ones do you think developers struggle the most with?
Nicolas Carlo 00:43:01 It’s a good question. I think, well I mentioned in the book I talk about doing smaller commits in general and that’s an advice even if you don’t know it by the name I use like micro committing. I think that’s an advice most engineers have received at some point and yet even myself like I struggle to actually do that and the reason was okay, I know I should do small focused commits but when I’m into it, when I’m working I do not think about doing a small commit. It really takes a lot of discipline and learning the moves to have like refactor, small refactoring moves for example. There are good candidates for making a small commit. You do a little extract function; you do a commit and that’s out of the way and you can iterate. I would say that’s a technique people struggle the most with in general because they know it.
Nicolas Carlo 00:43:58 But in practice how do they do that? The Mikado method is a good solution to that because by design the commit you will do, they will have less than 10 minutes of work. That’s one I would say practicing refactoring moves. So I mentioned a few incremental refactoring you can do. These will also help you do smaller commits. And in general the technique I used personally to get used to like to train myself to do smaller commits was to use, I use a gym timer, I don’t have it here, but I have a gym timer. The difference with the regular timer is that it’s a timer that buzz, a set interval like every five minutes for instance. And I remember putting that in my pocket and every five minutes I will get a little buzz in my pocket and that will just remind me of hey, maybe I should stop and do a commit, maybe not. But it was a nice way to have a constant reminder while I’m working that okay, maybe I should do a small commit here. I don’t use it anymore today because I found myself too naturally, I have the habit of now like thinking about hey I should do a commit. But if you’re struggling to get a new habit, for example, drinking water frequently, a gym timer, it’s an actual very affordable way of getting into a habit.
Sam Taggart 00:45:21 Very cool. That’s great advice. So my last couple questions are what have you learned since writing the book?
Nicolas Carlo 00:45:29 That’s a good point. I wrote the book two years ago, well actually almost three and I still use most of the techniques that I described. So because I did that work earlier this year, I was like okay, from the 14 techniques I might still like as I still relevant and they do. So that’s the great stuff about legacy code is in general what you’re talking about still applies long time later because we still have to work with legacy code bases and the concepts are the same. What I learned, of course everything that we talk about regarding AI wasn’t something on the horizon two, three years ago. So that may change. There may be new approaches and new ways to combine the traditional techniques with like powered by AI could be interesting. Then I had interesting insights about approval testing. So approval testing is a technique I describe as a way to cover existing code with tests, fast. But Emily Bache actually did a couple more follow ups on this to show that you can use approval testing also to produce new code. And this is not something I had in mind first and I realized later that in some occasions, yes, if you have a good printer you can actually in the book I said you should ditch this test as soon as you can, but maybe not in some cases it may not be the case. So that will be a change I will make.
Sam Taggart 00:47:03 That was a misconception that I had too about approval testing. So yeah, you’re not the only one.
Nicolas Carlo 00:47:08 No, I think David Farley also presented approval testing the same way in a recent video and I was like, you also think you should get rid of this test. But it again, as usual it depends in my experience, it depends on the quality of the printer and if you can come up with a printer that makes sense and make the snapshots useful from a human perspective, it’s more than just an anti-regression test.
Sam Taggart 00:47:41 Yeah, if maybe wants to learn more about approvals, I did an interview with Lalin not that long ago that it’s also on SE radio. We’ll throw the number in the show notes. Very great stuff. One last question and that is, have you learned any new tools since you wrote the book or?
Nicolas Carlo 00:47:58 Yes, I tried and failed a little bit, but something that is okay really niche at this point and it’s called multiple development and you can find the only tool I know that is doing that today is called Glamorous Toolkit and there is a small community of people doing that. It’s a completely different way of thinking about development. You still code, but you shape your coding environment, so your editor with code, so it adapts to whatever problem you are solving. It’s a bit difficult for me to explain because I’m not an expert in this, but I’ve practiced it a little bit and that’s interesting because yes indeed you can craft like your editor serves as documentation and visualization tool of your code base at the same time. And I think there is a potential here for some legacy systems because it’s totally part of what that thing can do.
Nicolas Carlo 00:50:05 If the language you’re working with doesn’t have all of this, it has a huge impact. For example, you are working with healthcare, or I don’t know, finance or something that is not just legacy web application. It may be worth it and I’m sure people who are more experienced than me will say no, you can actually use it in much more context. For the moment, my position on it is there is a huge cost, but there is a very interesting benefit. So in some situations I may consider using that and that’s something I wasn’t aware of when I wrote the book. I would not include it yet in the book because it’s not something I use yet. But if people want to broaden their mind and about what’s possible to do, I encourage you to look at Glamorous Toolkit.
Sam Taggart 00:50:57 Great. Thank you so much for sharing all your wisdom with us and for writing the book. I personally have read it and I find it quite useful, and I refer to it a lot. So thank you.
Nicolas Carlo 00:51:08 Well thank you for having me. And I always like to share a lot of techniques and tips. I collect all of the tools and like a magnet that tries to grab all the resources on that topic and then I put them on the blog and on the book. So thank you Sam for having me
Sam Taggart 00:51:26 For Software Engineering Radio, this is Sam Taggart. Thank you for joining us.
[End of Audio]