82. Working effectively with legacy code | Michael Feathers



Michael Feathers is a well-recognized programmer in the IT industry, the author of the famous programming book Working Effectively with Legacy Code, and the founder of R7K Research & Conveyance.

Michael talked about the content of his book, what is his definition of legacy code, how to work with legacy code, Why tests are important, etc.


Sponsors

FormAssembly

This episode is sponsored by FormAssembly.

22 Ways to Use FormAssembly for Remote Work Success – Learn how to streamline remote work processes with FormAssembly’s all-in-one form builder and data collection platform


Links


Video Teaser

The YouTube Video URL


Contact Me

If you enjoy this podcast, please reach me out to let me know your thoughts or simply say Hello. My (Xi’s) contact info:

Take care, until next time :)!

Transcript

AI-generated, unedited.

[00:00] I'd like to welcome our sponsor Form Assembly. You can find out how Form Assembly helps streamline remote work processes in the free ebook that we've linked in today's show notes. Form Assembly's all-in-one web form platform lets you create forms for just about any use case. From contact forms to donation forms, all while take advantage of useful features such as notifications, e-signatures, and more. Not only that, but you can also connect data to systems you already use. Form Assembly integrates with Salesforce, Padal, PayPal, and many other common solutions. Whatever your data collection needs are, you can be sure that Form Assembly keeps your data secure with encryption at rest and in transit on all plans. Plus compliance with GDPR, CCPA, and more regulations. At the end of the day, form simply helps you save time, money, and effort while getting the maximum benefit out of the data you collect. And I remind you, when you support our sponsors, you support the show.

[01:26] Hey everybody! This is Xi Xiao. This is yet another new episode of Salesforce Way podcast. Today I'm sitting with the. Excellent guest with me. His name's Michael Feathers. Hello, Michael. Hey, how you doing? Great to be here with you today. Yeah, thanks a lot. Really great to have you on the show. So, Michael, would you like to quickly introduce yourself? Yeah, sure. So, my name is Michael Feathers, and I've been in the industry for a long time. I guess 25 years, maybe something like that. And spent a lot of time working in biomedical software, and ended up going and getting into consulting. Right at the time that Agile was being developed, and so I learned some very early practices, test-driven development, and you know refactoring, even before test-driven development had that name. And I started going around with teams and helping them go and make things better. But early on with that, I discovered that as people were trying to transition to Agile practices, they wanted to refactor, but they didn't really have test coverage in order to be able to facilitate that. So I spent a lot of time working with teams figuring out how to do this, and end up writing the book Working Effectively with Legacy Code, which is really all about gaining coverage to support refactoring and making things better. And I thought when I wrote that book, it's like you know I've got this out of my system, and the world gets to learn how to do this, and everything is fine. I go on to other things, but it's really pretty much turned into my career. So now I spend most of my time seeing some of the worst code ever written because people want my help with it. So yeah, that's pretty much what I do, and I think the other thing beyond that, I would just go and add is that there is this way that all this stuff kind of like plays back into the social realm of things as well too, because

[02:56] it doesn't take too long before you start to discover that process and. Social arrangements going to impact the quality of code and the durability of systems over time. So yeah, that's a focus of my work as well. I see. That's interesting. Yeah, exactly. Because of this excellent working effectively with legacy code book, I've read it a couple of times because it's to me it's like a a tour book. Because I cannot remember everything, because there's so many patterns, so many principles there. So whenever I have puzzles, I go back to the book and see what's what's your answers there. What's interesting with this too, because I actually wrote the book and then rewrote it before delivering the first copy to the publisher, and it was really an agonizing experience because I had a short amount of time. But the way it was first written was a lot of theory in the very beginning, and then moving to techniques and stuff like this. And I was as I was finishing that. I realized nobody wanted to read all that theory; it would just be kind of ridiculous. So I decided to rewrite it by going and naming every chapter after a specific problem. Is saying okay, you should be able to look at the chapter title. Like this method is too long, I feel frustrated or something like that, and then just find from that title, you know, the thing that you're interested in and go and dig into it. So I'm really happy I did that because it makes it more of a a recipe book in a way. It's kind of like you don't have to read it cover to cover. You just basically go ahead and find the problem that you have to deal with. Get some advice about it. Yeah, as I talked to Uncle Bob, he mentioned not on the podcast that one of the most depressing book you need

[04:26] to read is this one. In fact, it was like the good, but I mean it's a fantastic book. I I really enjoyed it. It was written or published. Oh, that two thousand four, two thousand five. Yeah, it's about fifteen years old. So it's been sixteen years. Yes, yes. Do you think those content still apply nowadays to our modern, you know, compute science or whatever Salesforce even? Ah, yeah, I think they do definitely. I think there's there are some things have changed since its publication, but the thing is that you know, essentially, we know that old code never dies. And even beyond that, code bases are prone to the same dynamics that end up leading you to the same kinds of problems. So, yeah, I am, you know, constantly encountering teams with freshly written code that can be that can benefit from some of those techniques. I think the if I had to put it in a nutshell, a lot of. The stuff that happens is that we write code and then we kind of expand it instead of going and adding new code. Right? It's easy to add to an existing class rather than to create a new class, and it's easy to add to an existing method rather than creating a new method. So it's almost like if you look at you know fruit on a tree, it's kind of like the fruit grows and grows over time and then it becomes rotten. Right? I think a big piece of guidance for people as they're going and growing systems. Is to go and basically favor the creation of new abstractions continuously, because then you don't end up with these giant pieces which are hard to understand. I

[05:56] think it's more than a metaphor, really. That organic systems, like you know the bodies of animals and the bodies of plants, have similarities to systems, right? To code systems, they both tend to grow, and that's just a The reality of systems. So yeah, I think the big message is that you know when this kind of growth happens, you have to basically try to cut things down into pieces. And if you're not doing that continuously, then it's just going to go and get crazy. And you need to have a good practice on cutting it down into small pieces. Yeah. So it's not easy. No, no, it's not easy. I mean, the thing about it though is, it's like anything else. The more you do something, the easier it is. The more it's becomes second nature. Little story around this. I years ago, I used to live in Miami, Florida, and several people from a company came down for me to do a training for them, just for three people. In order to go and teach them refactoring, and they were going to go and sort of go back and tell the rest of the company where they wanted to go and purchase the bigger course. And halfway through, one of the attendees was like, "You know, why are you making us do these exercises by hand? We can just read the book, read the refactoring book." And I'm like, no, you don't get it. Essentially, unless you do these things a number of times, you don't really have the muscle memory to know how to do them in the context of the work that you're doing. So there is this thing where, for a lot of these practices, the more that you do them, the more they just become second nature to you. And once they do, then it doesn't feel hard at all, right? Yeah, indeed, that's

[07:27] exactly the things I'm lacking because I. Start my professional programming career just for two years. Before that, I was working IT, but I never wanted to be a programmer. And I know a lot of like principles, ideas. I talk with you, talk with other famous programmers. I know a lot, but it would go down to writing code. That's something I'm lacking, really lacking. So when I go to interview, they want me to write the code on the fly. Then that's something I can't do very well. Yeah, yeah. It's a matter of what you're interested in too. You know, it's like I guess another thing with this too is my first major in college was architecture. And I started to notice that the physical architecture. Yeah, physical architecture. Okay. I had never really done very much practice drawing, right? And it's kind of like I think some people are just driven to draw, and then they basically they it's just easy for them to draw these things, but it takes practice, right? Yeah. Indeed. There is another book also called Refactoring from Martin Fowler. I haven't had a chance to read that. So, what what's the difference, if you can quickly? Oh, sure. And I really recommend that book highly. The big difference, the Refactoring book was actually written a couple of years before mine. Was that he doesn't really deal with issues of testing. But what he does in that book is he basically goes and shows you ways that you can make code better, step by step, right? And but he just doesn't really talk about the. The support of testing that you would need to go and do some of those

[08:57] things. I don't know why he actually chose not to deal with that in the very beginning. It might have been that. There was an assumption that people would have good test coverage, and it might have been the case with the teams he was working. But that actually left an opening for my book in a way. But I think the great thing about that book is that he shows you all these techniques for making code better, like taking big classes and splitting them into small classes. How to basically adjust inheritance hierarchies and stuff like this. But he also has this interesting notion of something called a code smell. Which is really kind of like a description of a problem, and it's great that there's like he introduces terminology for these things. So I really recommend this because when you're on a team, if you can start talking about. Yeah, particular code smells by name, then you have a common vision of what is a problem in the codebase and what needs improvement. Just like when we talk about solid principle, everybody knows what is solid nowadays, right? Yeah, yeah. So it's um, it's very much the same thing. I think that when we develop a common language, you know, in a team, it really helps us go and sort of identify problems and be able to have a shared vision about what things become. Yeah. So, do you mean that both you and Martin Fowler, you both agree, test is important when you work with legacy code? Yeah, yeah. And I think in in his refactoring book, he does mention that testing is very important. It's just it wasn't the thing that he was emphasizing in that book. He was really emphasizing the the piece of refactoring that you do. When you have the test support, what is your definition of legacy code? It's interesting

[10:27] because yeah, there's many different definitions you can apply. In the historical definition of legacy code, code you got from somebody else, right? But early on, I basically offered an alternative definition, which is that legacy code is code without tests, and that may seem you know like a strange definition, but it was really coming from experience. That I kind of noticed that when you have good test coverage, it changes the way you can interact with your code dramatically. Right, when you have decent test coverage, you can easily start to refactor things and make things better. Without that coverage, it's kind of like you're just scared because it's very possible that. The things you do to make things better end up going and just introducing bugs accidentally. So I felt that defining things that way gives us almost like a an impetus to going and doing this thing, which makes things overall better, which is going to increase the. The test coverage you have in the system. I see, I see. Because I really enjoy this definition when you say that code without the test is legacy code because it it has nothing to do with the age of the code anymore. Right. Even if you write yesterday and you didn't have a test, that means it's legacy code. Yeah. But that's a good thing in Salesforce. Is that if we deploy your code to production, the Apex code, seventy five percent. Yes. Yes. You know that's not on the website. Yeah. Take a look before I came on. Okay. Was it a good thing? Does it put the standard higher,

[11:57] higher quality for the overall? Code base. Well, that's an interesting thing too, because I'd be really interested in like what is the average if you have that kind of a rule in place. Does it really go above seventy five percent? You know, in practice. Where does everybody? At least the code execution. How many lines of the code was was executed when the test was running? Of course, it doesn't mean like Uncle Bob also mentioned that if you don't have any asserts and then you just let the test run, still it can't go 100% coverage. Yeah. Yeah. I'm kind of wondering though. You know, it's like if 75% is the limit to get it into production, does it really ever go above 75%? I don't know. And that's the thing. I think that you could actually mine the data and figure that out, right? Yeah, sure. The danger with this, I mean, it can be okay. But I remember visiting a team in in Texas years ago in the U.S. And yes, we'll get back to what Bob was saying a bit. But they were asking me to go and look at a lot of unit tests they have and go and offer a critique of them. I noticed that there were lots of tests that were basically taking some extra extra paths they didn't really need to, and they weren't all that readable. And then I realized that basically they had this organizational goal to go and basically get test coverage to increase for every team within the organization, and every team was graded upon that. And so there is this thing where, essentially, by having a hard goal like that, sometimes people will accidentally game the thing that they're doing in order to go and just sort of get the coverage number, which is not a thing that you would necessarily want to have. So there is this thing that

[13:27] sometimes having a short-term goal like that is a decent thing. But you also have to go and pay attention to what the effects are. You know, are the tests are being written really good tests? And that's something you can probably try to figure out by inspection and review whether you're really getting that sort of thing. So you know, 75% seems like a decent, like a good low bar on things. So you would hope and encourage people to go and basically do better with that. I see. Do you enjoy working with legacy code? Why I'm asking is, you know, nowadays I would assume all your clients are asking to do this to help them to work tackle the legacy code. Is that you get a lot of experience just working with the legacy code? But do you get really sick of it? You know, it goes in phase. I've been doing this for a long time, so it goes in phases, right? There'll be times I'm just very sick of it. I basically think about other things, even though I do the work with clients. But um, yeah, it's really kind of expanded out into a number of things. But there's a lot of aspects of it that I really do still enjoy because it's like it's like solving a puzzle in a way. You know, when you when somebody hands you a function that has like. The nesting is like seven levels deep, and you've got variables all over the place, and you don't really really know what's going on. One quote I always go back to is Ralph Johnson, who was one of the early he was one of the co-authors of the original book Design Patterns from 1975. That introduced the entire notion of design pattern in industry, and he said that when you're refactoring, it's kind of like you have this window and you're wiping it clean with a rag. And the thing is that the more the more that you wipe,

[14:57] the clearer it becomes. And it's kind of like the same thing happens with like a large class or a large function. As you start to extract pieces, then you're starting to go and basically discover what the real structure is underneath. It's almost like archaeological excavation. You go out in the field and you start digging, and it's like suddenly there's a city hidden beneath all of the grime and the and the mud, and you get to explore that city. So I think you know there is this aspect where it can be kind of exciting to do this. I think if I have one regret about the legacy code book, it's that I did frame a lot of these things kind of negatively. When there's also a positive way of going, that's why Michael Boss mentioned that. Yeah, you know, and but it's it is the thing. You know, I did have a friend early on who was going to write a book about test first user interfaces. It was never published, unfortunately. But he had this chapter called the joy of legacy code, and I thought it would have been a very funny title for a book—the joy of legacy code, right? But there is interesting framing you can use with this. That you know, you're you're exploring a jungle, right? You have your knife in your hand, and you're cutting through the vines and trying to figure things out. I think sometimes with the proper mental framing, and some of these things become a bit easier. From my experiences that I have worked with like legacy code, as like a support person for a codebase. And I do enjoy that, as you mentioned, you do a lot of puzzles, you improve the code, make yourself happy as well. But it's really hard for me to measure because all of my other teammates

[16:27] they are supporting different customers, doing new projects. Do is my skill improved faster than them? I don't know. That's really hard for me to. I don't think there's just one single direction for skill either, right? I mean, okay, you can be skilled in many, many different things. I think one of the things that you get from doing a lot of legacy code or maintenance work. Is this thing where you encounter patterns in the wild about how things grow, and then you start to go and get a deeper sense of? Of what works because you're seeing things that are working against all odds, right? It's kind of like they're working you imagined they actually work. So yeah, getting a deeper appreciation for what's there, I think, is a different thing that you can get as skill. You know, if you start to when you look at things that are kind of messed up, and then you see a better way to do things, the skill of going and seeing what the better way is, regardless of what's put in front of you, is handy. The thing I can offer as an example of this, I don't watch much TV, but like in in the U.S., there's a cooking show where they invite a bunch of people in as this game show. And they basically say, okay, well, we're giving you these five ingredients. Go and cook something. And they give them, you know, a very short amount of time to cook something. And sometimes the ingredients are very strange. But you know, it's their skill to be able to go and take what's there and make something out of it, regardless of what they've been handed. Is a pretty powerful thing, and I think you see the

[17:58] same thing in music. Also, it's like the sometimes the best musicians that you'll ever encounter aren't the ones who've been with one band forever. But they're actually the studio musicians. Where somebody says to the guitarist, "I want you to play a reggae beat now." Do country western. Now I want a little bit of salsa with this, and to basically have the skill to be able to basically work in any style. You get that because you are constantly confronted by different things. So you learn to be very reactive. And I think if you are only working on greenfield code, you know you have that vast open frame, you know the empty page, and you can do anything there. But you haven't been given the constraints that help you grow as much. So I think there is additional skill that you get from having to be reactive to different code bases. Thanks for the advice. Yeah, I want you to still go back because you mentioned you reorganized the book structure. And I know your book have three parts, which really is clear to me. Would you want to quickly introduce what are those three parts? How do you organize? Yeah, well, pretty much the the beginning is just some background information, things like asking why we would want to go and write tests, what the hard parts are, dependency breaking, introducing the concept of a seam, right, which is kind of like a place where you can easily substitute one thing with another. So yes, a lot of preface in the very first section. And then the next section, really, which I consider the core of the book, is a set of chapters where each chapter is named after a specific problem, and

[19:28] you just go to that to basically figure out how to go and start to approach the problem. And that middle section makes references to the third section, which is really almost like a catalog of dependency breaking techniques. Which is really, I believe, t here is about twenty four of them, and they are all about ways of going and. Without tests, going and sort of like being able to replace something or isolate a piece of code well enough to be able to start to write tests for it, and that's really the core of things, you know, with the book. I see, I see. Because when I read the first part of the book, it's like a reasoning with me. When do you want to change the code, and what the risk involved, and what you should do, something like that? I was nodding. Okay, yeah, it makes sense. Makes sense, and then when you go to the second part, is like those scenarios. I was like. Damn, this is really exactly matching with my my daily work. What I see with the customer, you know, jobs. So, for example, there was I just have like one example here is like I, this is a scenario like I don't have much time, but I have to change this part of a code. What can I do? Right, that's one of scenarios in the book. It was really fantastic. Well, thank you. Yeah, and it really is that thing of like this is you know I wanted to approach the reader. It's like you know imagine myself being the reader. I'm in a situation. I need help. What do I, you know, describe the problem? And what can you do? Because in the past, in multiple episodes, the guests have shared with us

[20:58] that it's important to have tests surrounding your production code. Even better, if you can use TDD to write your test, so that always makes sure you have have high quality tests. And those things we understand, and also how to depend, break the dependencies, but we are not in the ideal world where in the in the rush every now and then, and the customer doesn't understand why do you want to write test since the production code is working okay. So there are all these scenarios, all these situations we need to handle as a program. I really enjoy that when you when you mention these. It's not just like you know a toolbook. It's really like this is the daily situation you will encounter, and this is how you can handle that. Yeah, thanks. It's good to get a reminder of that because you know as I'm doing other writing and stuff like that, it's kind of interesting that I I don't use that format as much now, and perhaps I should. You know, it's funny. It's a weird thing with this too, because when we're talking about the book now, it reminds me of things that I've learned since the book that I'm kind of like. I have some of them on video, but they're not really like you know written out yet. But one of the things I enjoy talking about a lot, which is really more in that realm of understanding what's good, is how testability and design interrelate with each other. And I really, really emphasize that when I'm teaching now. Just that I think if I try to put myself in the mind of the person who's confronting problems. One of the things I get scared of is that sometimes I think people are going to just look at this thing of writing

[22:28] tests as being just extra work that they're supposed to do, and a lot of a lot of developers, yeah. And what's rough about that is then it's kind of like then it feels like a chore, and then you're kind of like you know why should I be doing this? It's just an extra piece. But I always want people to understand that it helps them, right? Helps them basically do their work and have more. Have less stress when they're changing things. But a deeper thing with this too is that when you encounter pain when you're writing tests for things, almost invariably, what that does is it indicates problems in your design. And if you can basically figure out what the design problem is that's making testing hard, then you have a way of learning about better design just through your experience. I think that's a pretty there's a synergy between test code and production code, right? So I do have a video, and maybe when your podcast goes out, you might be able to put a link to it. But it's a video I did a long time ago called "The Deep Synergy Between Testability and Good Design," and I think there's something. There's something really deep about that, and that you know, I I don't know. I think it's because I have a bit more of like a science mindset than engineering sometimes, but. This thing that you know, if you as you work, you are able to discover things. Like if I find a different way to design something which makes testability easier, and by the way, the design is better in different ways. You know, I feel like I've really learned something that's made me better as a developer. And so, you know, our work can be a process of discovery that helps us improve our skills in addition to

[23:58] generating wonderful things for our clients. You know. Do you think we need to use TDD? Because some of the developers they just don't enjoy TDD, and they say they do this kind of like a in parallel thing a little bit, but not really like the TDD way. Of course, it's not like at the end of the production code, then then paste to get all their tests. I think TDD is a bit controversial that way. The it's it's funny. I remember when Kent Beck, who kind of like coined TDD, you know, and wrote the first book about it. When it was starting to become a bit popular, he was one thing he was doing is he was calling some of the practices that were part of extreme programming back then, like TDD, calling them like etudes in a way, E T U D E, which is almost like a It's almost like a small musical piece you play as a musician, just to be able to improve your skills. And I remember myself and some of the people around him kind of reacting badly, saying, "No, people should do this all the time," as opposed to just basically doing this as a practice thing. But you know, in retrospect, I really see the wisdom in that. In that, I don't think that you have to do these things all the time, but you have to do it enough that you start to see where the tests are going to support you. And you never get your code into the place where it's untestable. I think that's the most important thing, right? So I will write tests as I go quite often. Then sometimes I'll basically kind of skip a little bit, and then kind of backfill tests when I need to. But I hardly ever, as I'm writing

[25:28] code these days, get myself into a situation where I write something that's hard to test. And that's the powerful place to be in with us. And the reason it makes it powerful is that testing is a way of talking to your code and asking it questions. So if I can easily take some class I've written and say, "Well, gee, there's something kind of wrong here." Okay, let me create a test harness, instantiate the object, and go and ask it some questions. If that's really easy to do, then I'm able to go and just discover more about how things work. Discover bugs, get deep in my understanding almost whenever I want to, as opposed to being in the state that we're normally in, which is kind of like, oh, I don't understand how this works. Oh, I can't even cut this piece out. Enough to be able to put it in a test harness. That's going to take a day to do this. It's going to take a couple more hours. That's when things are crazy. That's when it's hard to do work. I know that on the last part, the third part of the book is those twenty-four dependency breaking dependency recipes. So you and then quote back to what you just mentioned is that if even if you don't write test code at all, your production code could have been better than other developers who don't write a lot of coding in the past. So because you know these kind of dependency breaking issues, you know this. How to write code. That's easier to create test the code. Yeah, I guess the thing I would say with this is that it's like the story was. I've told a story about like

[26:59] people. I was doing some training and basically going and saying, somebody in the training says, "Well, you know, we can read this in the book. Why do we have to do the exercises?" Right, and it really comes down to this thing of like, how do you know something? You can know something by reading it, but I would argue that when we just read something, sometimes we don't really know it. You know, we have to actually go and struggle with that, write tests with code, and see what that does to develop a deeper understanding of things. So I think it's more than just it's more than just kind of knowing these things at the surface level. You have to spend some time writing tests for code as you. As you do your work, and then basically that stuff becomes a—it almost becomes second nature, like a deeper intuition about the stuff that you're doing. And you know, I don't want to minimize it. I do write tests all the time when I'm writing code, just because I want to give myself the assurance that I'm not fooling myself that this particular thing works. Because a lot of Salesforce developers are not so familiar with TDD. The one thing I want to ask is that is writing TDD code slower than the traditional way? Go with the production code and then later cover the the tests. I don't think it's slower, but I think it feels slower, and that's gonna be a thing which is kind of weird with us. I think in the beginning we can easily look at something and say, okay, well. If I just wrote the code, it would have I would have been done within two hours rather than taking the time three hours to go and do this. But the thing about it, I think sometimes we fool ourselves, and I think it has to do with the way that we, the way that we reflect. We reflect on the stuff that we're doing.

[28:29] This is going to be a weird thing to describe, but let's imagine you're doing TDD, okay. When you do TDD, you are going to write a test, see it fail, write some code to make it pass, and then you'll look at it, maybe refactor a little bit, and then do it again and again and again. And after doing this for twenty or thirty minutes, you'll look and you'll say, "Well, I've only got, I've only made like twenty lines of code, for instance, but look at all the work that I did." And you can think back about all these little pieces of work that you've done and say, "Oh my God, that's a lot of work." And in your mind, it looks like a lot of work because you remember every piece of it, right? But here's what happens when we don't do that. When we don't do that, we spend a lot of time thinking, and then we do a little bit of stuff, and we spend some more time thinking, and just really focusing and focusing on what's going on with things. And when we look back, we think about the couple, the time we spent thinking and stuff like this. But there's no. There's no markers in our memory of the things that we did, but all that thinking time is almost like dead time in a way. It's kind of like you could spend 20 minutes thinking about something and just think, well, I just did one thing, I just thought, right? Whereas if you look back and you see all the pieces of work, it looks like a lot of work. But I think at the end of the process, if you did the same thing with TDD and without, you get to a certain point where basically things go faster because your work is supported. Your work is supported by having the tests to go and give you surety about what you're doing, and you spend less time basically going and thinking and trying to understand how things work because you can press a button and see that it's working. And so there's this

[29:59] place in which you go faster, because your work has this support. So yeah, there's two things. One is that you do eventually go faster, and the other thing is it doesn't look like that in the beginning because it looks like you're doing more work, or taking more time. And you know the fact is it's probably not as much time as you think. It's just that you have. More in your memory that you can refer back to about pieces of work. So that's my take on it. And sometimes I also have a kind of similar analogy: is that, like running a marathon. If you are doing running too fast at the beginning, it seems like you are going really fast to the customers or the project stakeholders, but at the middle or at the end, it's really suffering for the runners. You get a lot of issues with your heart, but if you keep the pace and then steady, and have all the tests that surround your code, you know that things will work. And you just click a button, get all the tests to run, to make sure the quality is there. It's a very old story. That's one of Aesop's fables. So, like a early Greek storyteller, like the tortoise and the hare. Okay. The story of this, and it's kind of like the the slow tortoise that goes and moves at a steady pace versus the, the hare, which is the rabbit that goes and sort of you know, goes too fast and ends up going and getting in trouble. So yeah, this is this is like it's almost like knowledge just thousands of years. Okay, okay, I got it. We rediscover. So Michael, you have tons

[31:29] of experience working with legacy code. Nowadays, do you still learn new stuff on this topic? Yeah, I do. I do, and I think. Most of the stuff that I really learn is now, at least, it's really about how to better explain certain things about this, and yeah, I guess different ways of going and seeing problems that lead to different solutions. So yeah, there's a lot of stuff that kind of goes in with that. I think the thing that I'm spending more time thinking about now than anything else is really how testing and modularity kind of interact with each other, particularly as we look at more more modern ways of structuring solutions. So I don't know if this comes up in Apex or not. I was looking at an example that somebody gave me of a testing problem, and it involved a bunch of async calls in .NET. Right, so essentially you can sort of like you call a function and basically has like an implicit wait where like a future object it gets returned back, and it's only when when you await that final thing that you're able to go and actually get the result back. And it seemed like this nesting of a wait async calls was something which. Was kind of problematic, you know, in terms of testability. And so I'm looking at this and trying to figure out, you know, is it really problematic from a design perspective as a whole, and what does that really mean? So there's a lot of reasoning. I'm basically going and doing this. I look through examples that people provide for me about how to deal with things. At least in Apex, that if it's async asynchronous or future calls,

[32:59] the test. There is a way you can convert it back to synchronous. So it's kind of like it's running synchronous. You get the result immediately within the test. Yeah, it's interesting because you mentioned that synergy between testability and good design thing earlier, and I guess I'll give you the video link for that. But it's it's like I think there is this deep thing where sometimes you know I'm not going to say that async calls are bad, for instance, right? But it's one of those things where. When we encounter a testing problem, there are things we can do to work around it with different features. But then the question becomes: Is there another way of structuring the design which makes testability easier, which might even be better by other standards? And that's the thing I think about a lot. Also, okay. So, for instance, with like um async calls, I think that one of the deeper decisions that we make in programming that people don't talk about very much is whether you're going to tell somebody something. Or ask for some data to come back to you. So I've ever heard of this, but like there's the Pragmatic Press. They basically write books and publisher. But they were developed by it's a company developed by Andy Hunt and Dave Thomas. They have a book called The Pragmatic Programmer that was written in the early two thousands. I think they just recently had a second edition come out. But there's like this one piece of advice they have in there called "Tell, don't ask." Which is really that, like, when you're in an object-oriented system, it's better when you tell another object to do something for you, as opposed to going and asking it for data that you get back. Right? It tends to be better from the point of view of coupling, and so it's interesting because it seems like from a testability

[34:29] point of view that tell systems tend to be easier in some ways. So, it's it's an interesting thing. Quite often now, whenever I see Systems where you're asking for data, I ask myself, what it looked like if basically we were telling we had the data and we told somebody to do something with it, and end up making things which are more like pipelines. So I'm really spending a lot of time thinking about that particular design issue. And trying to go and sort of get a sense of what testability tells us about that, and what alternatives might be, and how they might be better. I think you will put a lot of your thought results into your personal blog as well on Twitter, at least. Yeah, I do at times. I do at times. Okay. Thanks. So, Michael, do you have a plan to write a version two of your book? It's been floated. It's been a thought. It's a lot of work to go and do that sort of. Okay. So I kind of like weigh that against other things that I'm working on. There is another thing I've been working on, which I have to sort of like, you know, do somewhere. Either, you know, really settle to go and do it, or just put it aside. Another book that I've been working on called Unconditional Code, and the idea is really looking at systems from the point of view of conditionality. When do people make decisions in systems? And, you know, I find over and over again that when we try to go and remove conditionality from code, it makes things better. So it's a lot of technique around that particular thing. So yeah, I mean that's the thing that's on my you know table right now too. I've been kind of busy recently. So I'm looking forward to that. Excellent. Thanks, Michael. That's all. Do you have something else you want to add? How people can find you? Sure.

[36:00] The um the blog I have is Michael Feathers at Silverback dot com. So it's s i s i l v r b a c k. com so I have a blog there and I'm just on Twitter also m feathers and quite often I'll have links to things I've us blog entries so I'll put all this your information yeah and just anybody wants to get in contact by all means it's fun to talk about these things thanks a lot Michael well thank you thanks okay have a great day yeah. Hi,

[36:32] I am constantly looking for good guests. If you have any guest recommendation, please reach me out. I'll make sure they are joining to the show to share their knowledge. Otherwise, thanks for listening to the show. I'll see you next Thursday.

Leave a Reply