Crafting Code Podcast

~/podcast

$ cd episodes/031-clean-code

~/podcast/episodes/031-clean-code $ ls -1a
. .. episode-summary.txt references.txt themes.txt transcript.txt get-mp3.sh
~/podcast/episodes/031-clean-code $ cat episode-summary.txt

The concept of clean code is one that Dave and Allan feel is very important. But sometimes we hear or read of people saying it is unimportant or unnecessary in some cases. In this episode, we explain what we mean by 'clean code' and why we think it really matters. After all, it's exponentially easier to make a mess than it is to keep things clean.

~/podcast/episodes/031-clean-code $ cat references.txt ~/podcast/episodes/031-clean-code $ cat themes.txt ~/podcast/episodes/031-clean-code
$ cat transcript.txt

[00:00:16] Allan Stewart: Welcome to the Crafting Code Podcast, where we discuss the importance of doing the right thing at the right time with the right tools. I'm Allan Stewart, a software architect, and lately I've been thinking about balancing system health against seasonal needs for new product features.

[00:00:31] Dave Adsit: And I'm Dave Adsit, a VP of engineering, and recently I've been thinking a lot about AI. Is it a boon? Is it a bane? Or is it just a scam?

[00:00:40] Allan Stewart: The topic for this episode is clean code. Dave, what even is clean code?

[00:00:47] Dave Adsit: This is a question I've been thinking about for a long time, since I was first introduced to it when I bought a copy of Robert Martin. It's got to be forever ago now, when it was brand new. But in the last few years, my personal definition of clean code has come to be a code base. Let me scratch that a little bit, go back a little bit. Okay. In the last few years, I've come to think that a code base feels clean when the cost of delay to deliver a new feature is low relative to the value. So in other words, clean code is code that can be changed in a reasonable timeframe when our needs for the code change, or when we have a new feature we need, or a deeper understanding of the domain. Clean code should be maintainable and extensible without starting over.

[00:01:47] Allan Stewart: I like that definition. It's kind of working backwards from the result that you want. This is the outcome that we want. And so code that allows... That must therefore be cleaned.

[00:01:59] Dave Adsit: Right. Doesn't tell us a lot about what the characteristics of the code are along the way. It just tells us how the code behaves once we have it. Sure.

[00:02:08] Allan Stewart: I like that. And I'd agree with that outcome. My own definition is maybe a little bit closer to a book definition, I guess. But for me, it kind of boils down to code that is easy to read, understand, and maintain. And that fits with what you were saying. Mm-hmm. If you can... When you open a piece of code and you just... You don't understand, like, what is even going on in here? You're scrolling up, you're scrolling down. You're trying to divine the intent of these names, or like, what exactly does this function do anyway? Because it doesn't communicate that well. That is unclean. And it's hard to work in. It's hard to understand what's going on. And so you're more likely to break things. So yeah, that's one of the pieces of my definition. I also like self-documenting code as part of the definition. Mm-hmm. Eliminating the need for comments by actually encoding intention and meaning right into the code itself. And that way, if things change later, that's okay. Because a rename refactoring will pick all those up, and you're not left with these extra comments.

[00:03:28] Dave Adsit: Yeah.

[00:03:29] Allan Stewart: I'd also say... And this is kind of... I guess this one's kind of cheating, but just generally good cohesion and coupling. When I look at some code, and I see that things that don't belong together are all intertwined, and the coupling is super high, then I automatically just think, well, this is not very clean code, because they haven't separated individual concepts apart in a way that's very clear. And so I think that's a way that you can follow the train of thought. And then finally, consistent patterns. If I go into one file and it is formatted differently than the next file, and then the third file is yet different too, it's really hard to read. If people have different naming conventions, and it seems like 60 different people all independently were writing different bits of code, then it's hard to work through that. So those things kind of come together into my definition.

[00:04:29] Dave Adsit: I think it's interesting that you talk about good coupling and cohesion, because almost all of the patterns and practices... Not the patterns, but all the practices and techniques that we use in software development boil down to having loose coupling and high cohesion. Those really are core to what we do when it comes to software development. I liked other aspects of that definition as well. Yeah. Self-documenting code made me think a lot about the practice of having a ubiquitous language for the domain that you're working in, whether that is specific to the domain of software engineering or specific to the problem domain of the code that you're building. Yeah.

[00:05:12] Allan Stewart: And having some of both of those can be very useful.

[00:05:16] Dave Adsit: For sure. Almost essential. So I guess the question then becomes, we have definitions for clean code. Why does clean code even matter? Yeah.

[00:05:26] Allan Stewart: Clean code matters to me a lot around that coupling and cohesion problem. I want to work in code where I can go in and achieve those outcomes that you were talking about in your definition. I don't want to edit code just for the sake of editing code. That can be kind of fun. We've talked about the difference between code as delivering value versus code as art. And I definitely enjoy writing code. I think it can be really fun to solve a hard problem or just get in and see the computer bend to my will. But ultimately, day to day, I want to work in a system where I feel like it's not going to be really buggy. It's not going to be constantly plagued by firefighting and unexpected work because, oh, no, some big client X. Can't do the thing that they thought that they should be able to do and that you're just sifting through and trying to figure out what is even going on. I want to be able to write features that deliver value and do it in a way that is relatively bug free.

[00:06:41] Dave Adsit: Yeah, I think one of the things that to me is important about clean code and leads to my definition is that I think of coding as a craft. And our purpose. Our purpose in the craft is to deliver some kind of value for someone. Most of the time it's delivering value for the customers of our business or other employees of our business. And so to me, what I'm looking for in clean code is code that allows me to deliver value often and without too high of a cost. I guess what it all boils down to is just. I want to have a low cost of delay in creating new value for my customers and users. And so that can be accomplished in a lot of different ways. Clean code is one of the tools and techniques that I've used throughout my career to make that happen. Every developer I've ever worked with has wanted to have a positive impact on the organization that they're working in. They. We all. They. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. We. returns on investment in terms of dopamine hits for like, ah, I built a thing and somebody liked it and now I'm happy. They're happy and that makes me happy. Right. And so having that positive impact, I think is super rewarding, both emotionally, but also, I mean, if we're good at writing clean code, we get rewarded financially as well because we can deliver more, more often,

[00:08:40] Allan Stewart: more consistently. I agree with that. I was thinking back, you mentioned Robert Martin's book, Clean Code. And for me reading that book, it came at a time in my career that was very, very pivotal for me. And Clean Code is, is one of those pieces or like one of the things that changed how I view code, how I think about writing code with other people and so forth. It was around that same time that I was learning some other things about DevOps and test-driven. And some interrelated practices, but, but I do remember that prior to reading Clean Code, there was code that I didn't like, and I couldn't really vocalize what I didn't like about it. I didn't, I didn't have a framework or, you know, a rubric by which to judge this code. I just had just kind of a vague sense of, well, this seems bad. And honestly, some of the things that I But then I also just kind of mixed up with my personal preferences. I didn't have a lot of, you know, I didn't have a consistent way of judging that code, but reading that book in particular, and then some other related things around it. I remember I read Martin Fowler's refactoring book around the same time, and I could start to identify what bothered me in some pieces of code and be able to better communicate why I believed things should be done in certain ways. There's one experience that really stands out to me. I remember I was working at an educational company doing some kind of like multimedia, rich internet applications, what we call them back in the day. And it was educational software for students. So like K-12 learners. And there was one program in particular or piece of a program that would help them learn about integers. And like they gave you these integer chips and you could divide them. And so if you had six integer chips, they could be divided in half into three and three. But once you get down to one integer, that was indivisible. And you could create these different stacks and you could break the stack. And combine the stacks and probably multiply the stacks. I don't remember exactly what you could do, but the code for it was extremely difficult to understand. And it didn't always work. It would get into weird scenarios where it stopped working because the global, I mean, it was just a ball of mud global state.

[00:11:32] Dave Adsit: Can computers even handle integers really? Do we even know how to do math with computers yet?

[00:11:39] Allan Stewart: I hope. One day we will learn. Anyway, I went through a whole process of taking these things that I had been learning about clean code and refactoring. And I just slowly picked apart. Like these things belong together. These things need a new name. This shouldn't be global variable. Let's break it down. Let's identify what patterns. I guess another book around that time was learning a lot about patterns, like the Gang of Four book. And so I applied. I did a model view controller pattern. And it changed the structure dramatically. But all of a sudden it was working great. There were no more bugs. It was easy to make changes. Some of my coworkers were a little bit skeptical because it was unfamiliar to them now. That's a different. It was a different style of writing code that took some getting used to. But it's definitely left a lasting impression on me. Just the difference before and after of being able to take this code and turning it from a mess into something that I could make all kinds of interesting and useful changes to deliver additional value quickly, which couldn't be done before. Before we were taking several days to add each new feature. And then I took several days to refactor it and we could add a couple features every day.

[00:13:06] Dave Adsit: Right. Yeah, I remember it's been 16 years now. Since clean code came out. Surprisingly, I remember when I first was introduced to it, I was at a conference that Bob Martin was speaking at and they were selling his book, which had just been printed at the conference bookstore. And I picked up a copy and brought it back to my team. And I was on a team that was trying to do test driven development and not doing a very good job at it because most of the code we had predated the idea that we wanted to do automated testing. And I was able to use the clean code book as a way of teaching and reinforcing the concepts around what makes good code and how can we test it and ensure that it's working. And so it was super, super powerful, super useful for me in that in that environment that I was in at the time.

[00:14:05] Allan Stewart: Yeah. And it makes me think about how clean code is more like a process. Then an event, because you said that your code predated the desire to do any kind of automated testing. Right. And the code I've seen code like that. It actively resists testing because it is just so tightly wound together. But I think it's really easy to miss the mark and just assume that clean code is just going to happen. That there's some. Perhaps some magical people who are able to just write this beautiful code and it comes out perfectly the first time. And I have yet to meet somebody like that. Now, with practice, you start to learn patterns. And I think that there is some truth that the more that you practice clean code, you're going to write better code from the get go. But more importantly, it's this understanding of you're not just going to write code, get it working. And the first time that it works, you say, well, I'm done now. But then you take these additional steps to say, okay, how can it be improved further? How can this be more understandable? Is this thing that we just added related to this other thing that used to be in the code? Maybe we should merge them together or maybe something that we thought was the same isn't the same and should be broken apart. And it's that process of going through the code that actually ends you up in a place where you say, yes, this is clean. Yes, we can work through it rather than it just kind of magically appearing that way. Right. You know, flowing out. Of your fingers into the keyboard somehow, just because this is clean code because you loaded up your keyboard with a bunch of soap before you started writing it.

[00:16:03] Dave Adsit: Right. So one of the things that that makes me think is one of the definitions of clean code from the book Clean Code is actually code that pretty much does what you expect it to. Right. So that speaks to both naming, but also simplicity. And someone taking care. And so, yeah, that that is one of the things that you look for in clean code, right, is that it it ends up in a state where it's understandable, readable, maintainable, where you can make changes to it in a reasonable timeframe. It doesn't it doesn't necessarily start there. In fact, almost no code base that I've ever worked at starts. There so much so that some people would say you can't have clean code in the early phases of a project or a startup. What do you think about that, Allan?

[00:17:03] Allan Stewart: Yeah, I've I've heard this before, and I just I disagree because if you are successful, you have set future company up for a bad time, if not failure, just outright failure. Right. Right. Right. And so I think that keeping your code clean as you go is just it's just necessary for survival. So, yeah, there are times where I don't know what the code should look like. I'm doing something new, something I've I've not done before. Or there's there's new requirements coming in every day that maybe are changing very drastically because we're doing a prototype or the early phase startup, like you were saying. But if we just start throwing things at the wall. Yeah. Yeah. And if we're not able to make a mess, like making messes happens exponentially faster than cleaning messes. And so it's only a matter of time before you've you've generated more mess than you can afford to get yourself back out. Right.

[00:18:06] Dave Adsit: There's that concept of what is the total cost of owning a mess. And if you are not keeping your code clean, you are not able to quickly deliver new value. And if you're not able to quickly deliver new value. The chances that your startup or new product or whatever finds its product market fit before it becomes overly burdensome to continue maintaining it. That's that's not good. Not good chances. Right. The you're going to be the one thing that characterizes every startup I've ever worked at is that we have to go fast. And what do they say about going fast? Slow is smooth. Smooth is fast. Right. If we are making a mess, we're going to get in our own way.

[00:19:17] Allan Stewart: You know, another variant that Uncle Bob will say sometimes is the only way to go fast is to go well. Yep. And I think sometimes we get mixed up because you're exactly right. An early phase startup, or if you're building prototypes, you want to be able to iterate quickly. And you're going to have to have clean code if you want to maximize your ability to iterate. Or you have to throw everything away and start from scratch every time, which you're starting from a clean slate. And effectively, that's some clean code, right? Like there's no code better than and cleaner than no code at all. And I don't mean no code like, you know, use Excel. I mean, there is no code at all. Right. But that's not to say that you follow every practice, right? Like, I think that's where people get confused and they say, oh, we don't need clean code. No, you probably do. You want clean code. But that doesn't mean that you have to follow every practice. Every. Pattern. Clean code doesn't mean that you had to do a perfect hexagonal architecture for every project. And that the brand new thing that you're starting up that only has three database tables is, you know, perfectly isolated. And you've got, I don't know, you know, a snowflake schema for all of your data analytics. And you've got, you know, all of this extra stuff. Maybe microservices. Maybe you've got a bunch of services for one service for every table. You know, that like that's overkill. And it's not and it's not necessarily any cleaner to do your code that way. And we get confused. We mix up. We we confuse the idea of clean code with other concepts that are sometimes related and sometimes useful, but are solving different problems. Yeah.

[00:21:12] Dave Adsit: Well, what if our code has to scale to ones or even tens of simultaneous users? Then we'll be glad that we spent six or 12 months building that microservices architecture.

[00:21:23] Allan Stewart: Right.

[00:21:24] Dave Adsit: Meanwhile, we burn up all of our operating capital and go out of business.

[00:21:28] Allan Stewart: Right. And you're going to need those microservices for all the developer that is in your system.

[00:21:33] Dave Adsit: All of the one developer that you were able to hire with your meager budget.

[00:21:37] Allan Stewart: Right.

[00:21:39] Dave Adsit: Right. Yeah. So you're right when it comes to practices, there are a ton of practices that we can use. To support our journey towards clean code. One of the things that I pull out all the time, I think one of the first ones to think about is simple design. Right. You mentioned hexagonal architecture, simple design and another pattern for overall system structuring. Simple design. Basically you want to minimize the things that you have and make sure they're tested. Right. You want your code to be expressive and well-tested to good, good place to start. It's not always where we start when we are at the very beginning. very beginning of our journey. Maybe we've got a code base that's 10 years old and we're like, how do I clean from here? Well, I know they didn't do TDD and I know they didn't do simple design and I know they didn't follow hexagonal architecture. So now I'm going to have to start refactoring my way to glory. I can clean up in the area that I'm in. That's one of the concepts that I like from the clean code mindset, which is the Boy Scout principle or the Scout principle now, where you leave a space cleaner than you found it or leave a campground cleaner than you found it, leave a code base cleaner than you found it. If you are adding to it, don't add to the mess, add to the cleanliness of it. Refactor things as you understand them. You come into a method that's 200 lines long and you don't understand it and you start reading. Well, start applying extract method as you go. Once you understand what a block of code does, extract it and name it. Once you understand, what a variable is for, name it, these types of things, the little things that we can do as we go in a code base that help us keep it clean. And those are the techniques that you have to apply always. As you said, we rarely start with clean code. If we just write our first test, great, good start towards clean code. And now I go implement the solution to that test, implement the code that causes that test to pass. Great. Is that clean code? Well, maybe not. Maybe One more step of refactoring. So maybe even before simple design, the first rule,

[00:23:45] Allan Stewart: the first practice of clean code is refactoring. I could see that. And if you're going to do a true refactoring, you're going to need tests. Otherwise you're just changing stuff. Although if tests are hard and coming because you're in a legacy code base, I'll take a restructuring or just a hope and a prayer in some cases. But you get at least enough of a handle around something that you can start. Start getting some tests in there. But I also liked what you're saying. It reminded me of Don Norman's book. Is that a design of everyday things? Yes. And in that book, he talks about how research has shown that there's a limited number of things that we can keep in mind at any given time. And when you're reading through some complex piece of code, it makes me think about that, right? There's even, there's even comics that I've seen about this, where, you know, somebody they're, they're in the code and they're like, well, what does this mean? This, I guess, like there's this complicated, like mental graph, mental model that's forming. And then somebody comes and interrupts them and like all of the metal mental models falling apart and they have to start over from the beginning. Yeah. Well, refactoring is a way of putting that knowledge into the world, right? Going back to Don Norman, you put it into the world. So you Oh, well, let me rename it now that I understand what it actually is, whether it was a lie or it was just badly named. It was just X. And I don't know what X is in this, in this case, but well, now you don't have to figure it out again. And when you get interrupted, you're not going to have to remember what was X again. Oh yeah. I already changed it. I made it better by virtue of this continuous process of, of cleaning things as you go. For sure. Yeah. So if we, if we say not all

[00:25:40] Dave Adsit: these practices, are necessary, refactoring probably is necessary to make, to get to clean code. The rules of simple design may be necessary, may not be necessary. First one passes the test, then it reveals intention, has no duplication and has few elements, the fewest possible elements to implement the solution. So if those are the rules of simple design, I mean, you would say that code that follows those rules is probably pretty clean, not necessarily, but most cases probably pretty clean. Yeah. But you don't necessarily have to have all of those things to be perfectly clean. For example, one of the things that I put on my list of practices that I want to use almost all of the time is either TDD or at least good unit tests or guts. There's a talk my team watched recently from QCon that was about programming with guts. And one of the best ways to get good unit tests is to do test driven development. So do I want those? Usually the answer is yes. Do I always have them in every code base? No. Do I consider some of the code bases that don't have tests to be clean or at least clean enough for purpose at the time? Probably. Sometimes the tests, the tests I think of, I think of tests as a discovery and design technique, as well as a tool that I use to basically hold the code in place like a vice or a clamp so I can work on it without breaking parts I didn't want to break. And if I'm looking at this code and thinking this is a prototype that I'm going to throw, I'm going to work on for three days and then throw away, I may not write tests for that because that code is not intended to be long lived. And I may still consider it clean because at the end I'm throwing it away.

[00:27:29] Allan Stewart: Yeah. Another example I think of is the rule of no duplication. And I think that's a good rule, but I love our friend Matt's rule of thumb. What does he call it? It's basically three times is his charm, right? I don't know. The rule of three. The rule of three. That a lot of times in code, if there's a lot of things that are duplicated, that's a big problem. But if you are too obsessive about removing all duplication, then you start this downward spiral of trying to make everything just the same. Like it's all got to fit into this one bucket. If I can just use generic, hard enough, they will all be the same. And that doesn't make it cleaner. That actually makes it worse because some things that weren't meant to be duplicated are suddenly now, are things that weren't actually the same and should be separate are now combined. And so no duplication is one that I might in certain contexts ignore a little bit and say, hey, I'm going to allow for two or maybe even three of these things to crop up before I see what the rest of the code is going to look like.

[00:28:42] Dave Adsit: When it comes to duplication, one of the things, one of the concepts that I learned in language learning is the concept of a cognate, which is a word that is basically the same in two languages, right? But you also have things like false cognates, which are words that appear to be the same in two languages and are not. And I think that happens sometimes in our code base as well. Sometimes we, in our rush to avoid duplication, we take two things that were actually different. And force them to be the same. And then we later pay the price of trying to make one thing serve two purposes, right? So an example in Spanish, or in English, the word embarrassed sounds very, very similar to Spanish embarazada, which means pregnant. So you would not want to say I am embarazada if you are embarrassed because you would be instead declaring that you were pregnant.

[00:29:38] Allan Stewart: Which in turn would make you embarrassed.

[00:29:40] Dave Adsit: It would just increase the amount of embarrassment you are feeling when you realized what you had actually said, right? So if we are not careful, we run into false cognates. I think one of the things that often leads to not very clean code is the rush to abstract from a single example.

[00:30:01] Allan Stewart: Yes.

[00:30:02] Dave Adsit: If I go and I try to say, oh, I have one example of this concept. I'm going to create a factory pattern around it with the template methods and all kinds. Like, no. Pump the brakes. Move on. When you have two or maybe three, the third time you are implementing something, implement it to fit your current purpose. And then look at all of the places and say, are these really in fact the same? And can I remove this duplication? So one data point is not a trend. One data point is not a trend. And in many cases, two is not a trend. So there's a lot of other practices. Let's run through some of them kind of quickly, right? Like one of the things that I like to do is collaborative programming, whether it's mobbing or teaming or ensemble programming, whatever you call that version. Or the more simple and older pair programming where you only have two people instead of the whole team at the keyboard, right? I feel like these are tools that we can use. These are practices that help us increase the cleanliness of the code for a lot of reasons. One is working together, we're going to help each other remember and follow the rules that we've agreed to as a team. Working together, we have to communicate about the code we're writing. And communicating about it is the first step to making code that is expressive of the intent and the concepts that it's trying to cover. And so I like those tools. There's a bunch of other tools you can use as well to get some of the same benefits. But not quite as good. Like if we're using linters or things like that, those are very valuable tools and I would put them in place. I might not have them for the first six or 12 months of a project that I'm working on. And then I might add one. Or if it's really easy and I've set it up recently, I might set one up on day one so that I make sure that I never fall out of sync with the current coding style for the language I'm following.

[00:31:58] Allan Stewart: Yeah. And sometimes the linters either can't or are difficult to set up for certain things. um being able to to say you know what what is that thing that is you know that goes in the parentheses here is does it have a name and then we can use that name to refer to it in the future yeah it just it gets you to cleaner code a lot faster because just as you say we're working on it together and we're kind of coming to a natural consensus about how we want it to be an evolving consensus even rather than well we set up rules one time and hope that everybody follow it

[00:33:04] Dave Adsit: yeah well another another tool or practice that i like to use to ensure clean code is continuous integration and by continuous integration i'm going to be very explicit i mean every single developer on the team every single developer on the project integrates with main every single workday no other thing that you do will count as continuous integration under this definition right so every developer is integrating with main every single day and that's going to help us keep code clean because we're going to have to be working in small steps that we can commit and push we're going to have to be working in um with tools that allow us to basically put in code that won't necessarily get executed by users right so this is a technique that is often very useful for keeping the code code clean right we're not going to have big merge conflicts we're not just going to uh you know dump a bunch of code on top of each other at the end of the sprint right before we try to release and then have a problem with integrating it for days um it helps us keep the code clean absolutely again may or may not use it on every project usually i will use it on every project but there's times right another one that you and i have put in place at one of the companies we worked at together is observability actually understanding what the code is doing you goes a long way towards helping you understand how to change it effectively how to maintain it how to keep it clean right knowing you know logging monitoring knowing what methods are being called in what conditions is super valuable from my perspective and understanding the code it can actually even help you identify code that's never called and can be removed from the code base thus simplifying your overall maintenance load that one can be particularly

[00:34:57] Allan Stewart: difficult yeah ! you might be carrying around a bunch of dead code trying to maintain it trying to keep it working only to find out later that nobody has called that in over a year that that ap especially like at layers like a api boundary um so understanding that being able to to know what's actually going on in the code there's been plenty of times where i thought i knew oh we're having a performance problem well obviously the answer is x but then when you go and measure it it turns out that no that's not the real problem and only through measuring it are you going to figure out

[00:35:38] Dave Adsit: what was the problem so related to both observability and my personal definition of clean code is the dora metrics that you can track for your code base right we look at things like deployment frequency how often are we successfully releasing code the lead time for changes? How long does it take from the time I've committed a change to main until it is in the production environment? Change failure rate. How often does one of my releases actually blow up when it hits production? And then of course, what do I do about it? What is my mean time to restore service once I've identified a problem? So if you're tracking those things in addition to your basic observability, you have that much more insight into whether or not this is clean code. Can I change this code? Can I enhance this code? Is this code super brittle and I don't ever want to change it? Because every time I try it blows up and then I have a sad day, right?

[00:36:40] Allan Stewart: Yeah, they're lagging indicators of the cleanliness, but they're also indicating whether or not you're actually achieving the objective of the cleanliness. It's not just clean because you're, you're a neat freak or because of some kind of artificial ideal of, well, clean is better, but actually you're getting some measurable, demonstrable value out of the cleanliness. Yeah. Another practice that can help sometimes with clean code is having good documentation, right? If the code is good documentation itself, like ultimately the code is the only documentation of what the code really does because comments tend to lie. Right. But the code by itself doesn't often express high level intent. It's really easy to get down into the weeds of the code. And so having some kind of documentation about why does the product work the way it does? What kinds of personas do you have in your product? Or as far as product users, what kind of architectural decisions have you made? Reasons, you know, for why the things are the way they are. Yeah. and keep the code clean because you're not changing it in a way that gets it out of alignment of what the intent was for the product or the intent was for the architecture because you have a signpost there essentially that keeps you on track.

[00:38:14] Dave Adsit: Right. In most cases, I would say if your code is littered with Java docs, I wouldn't consider that super clean, but I do want to have things like ADLs in there, DRs and some kind of a log of the product decisions we made. It's exactly what you said. I want to understand why the code is the way it is. And I would consider most of the function names and the tests to be part of good documentation for a well-documented code system. Yeah.

[00:38:40] Allan Stewart: And it will depend on what you're delivering as your product. If you're delivering a code library that other people are going to be using, then maybe those Java docs are pretty important there. At the interface, at the boundary that they're going to be exposed to. But if the docs are just there for you and the other two developers on your team and no one else is ever going to look at that code, maybe it's unnecessary.

[00:39:05] Dave Adsit: Yeah. Hopefully all three of you know how to look at the method name and the method signature, including the return type, and infer what the Java doc would say if it told you the method name and the method signature and the return type. Right. So other questions? Other things, other practices that help us with clean code include all types of automation. We've talked already a lot about tests. Automating your tests is important. Automating your tests before you check in, automating your tests when you do check into your centralized server. Automating testing in many places is super valuable in helping you maintain and build clean code. I think other tools that I've used in the past successfully, static analysis, understanding cyclomatic complexity. And the coupling and cohesion across my system, visualizing that and looking into those concepts using automated tools to do that kind of analysis. I think one of the things that I reach for right away in most projects is automated build and automated deploy. I want every time I check in, I want the code to be built on a machine other than my development environment. And I want all the tests to be run. I want to run against it. And I want to see that it actually still works even not on my machine. Right. That is important to me. And then I want to deploy it. I want automated deploys, which help us to keep our code clean because nobody wants to check in code that's going to blow up the staging environment or heaven forbid the production environment. And so we're going to think a little bit more about the code that we're writing before we push it out.

[00:40:46] Allan Stewart: One of the things that I really like about automation and especially test automation is that by itself, it's not a measure of cleanliness, but it's kind of like setting the guardrails that allow you to make change, make change quickly and discover if something goes wrong quickly. Right. It goes along with the continuous integration that you were talking about before, like the trunk based development concept of like everybody get together often and we'll know if it's working or we'll know if it has a problem quickly while the change sets are small. And we can fix it quickly. So having automated tests doesn't necessarily mean that your code is clean, but if you can quickly find out that a change broke something that enables you to make more change faster and you can continue on that process of making things cleaner as you go, rather than assuming that because I had an automated test, therefore it is clean and it's like a state of being rather than. A process that you're continually moving towards. Yeah. It's kind of like that. That story from this is lean where they brought in the very well respected Japanese leader from Toyota. And they kept asking him, is this the, is this the leanest place that you've ever been? Look how great we are at lean. We've done this all over the place. Every part of our factory is so lean and he didn't really say anything. He was not enthusiastic about it. And they finally like it. Look, is this the best lean that you've ever seen or what? And he's like, I don't know. I wasn't here yesterday. I think clean code is that way too. I don't know if your code is clean or not. We'll have to see how it is progressing over time.

~/podcast/episodes/031-clean-code $ cat ../../copyright.txt

Copyright © 2026 - Crafting Code Podcast