Episode 8

Code Cleanliness and Organization

00:00:00
/
00:37:54

January 4th, 2023

37 mins 54 secs

Your Host

About this Episode

Today we talk about code cleanliness and organization and the importance of it all.

Transcript:

MIKE: Hello, and welcome to another episode of the Acima Development Podcast. I'm Mike. I'll be hosting today. We are going to be talking about code cleanliness and organization and the importance of that. Let's go ahead and introduce the other people who are here today. David, do you want to introduce yourself?

DAVID: Sure. I'm David Solano. I've been here in Acima for a little bit more than a year, basically programming Ruby on Rails. I would love to talk about this important subject.

MIKE: Great. Ramses, do you want to introduce yourself?

RAMSES: Hi, everyone. I am Ramses. I'm primarily a Rubyist, a little bit of JavaScript as well. So I'm excited to be in this discussion.

MIKE: Eddy, do you want to introduce yourself?

EDDY: Hey, everyone. I love these. Thanks for including me. As he said, I'm Eddy. Thank you for having me.

MIKE: Yeah, let's introduce our topic a little bit. And I've been thinking about a good way to introduce this topic. I wanted to start with a story and talk a little bit about my wife; she is an organizer. Let me clarify that there are a lot of people who like to have things organized. It's like something that they like; that's not what I'm talking about. My wife treats organization as a science. [laughs] She doesn't just think, oh yeah, I like to have things organized. She treats it almost professionally.

When she comes into an area of a home or a building and wants to make use of it, she looks at the space, thinks about the shape of the space, and thinks about it in great detail, does research. Her mind just gets cranking and figures out the ideal way to organize the space so that it's most useful. She's taken, classes. She follows prominent organizers (There's such a thing.) since before they were popular. It's like a thing she's brilliant at, a lot of background. And this spills over to other areas where she'll come up with better ways to do things like an algorithm for solving a problem that's slow; she'll think, well, why don't you do it this way? Oh yeah, that's better.

But just on a very small scale, we have a pantry where we store stuff near our kitchen. We'd buy stuff for years and throw stuff in there, and it just went there to die. [laughs] It wasn't very well organized. There was food in there that we liked to eat, but it would end up tucked behind something, and we'd forget about it. And we'd end up buying the same thing a while later, forgetting the original stuff was there. Then we'd go clean out like, oh, wait, this has gone bad. It was never very useful.

So my wife thought about that, did her planning that I talked about, got an appropriate set of containers, put in shelving, arranged the pantry so that everything that is in there is in. And, you know, we had to decide what we were going to put in there. There are some things that didn't get a go. And everything that is in there is an appropriately sized container that is labeled and highly visible on a shelf; there's no too deep anywhere. And things we use less of are in smaller containers. There's some shelving on the inside of the door as well that nests in, so it fits perfectly. It's kind of amazing, honestly. [laughs]

The interesting thing is you can't just throw stuff into the pantry anymore. But we use it far more than we ever did before. Although it takes a little bit of time to make sure everything's put in the appropriate bins, it's immediately obvious. You walk in there, and you know in a moment where the thing that you want is. And we use it multiple times a day. That's where we go for a lot of our food because it just works so well.

There are several interesting things that I've learned from this. Organization isn't just about convenience. It fundamentally changes the way that something can work. This area went from a place that we occasionally used for things we thought, oh yeah, I think we can have long-term storage in here, to kind of a fundamental extension to our kitchen and where most of the stuff that we actually cook with is because that organization allowed us to use it differently. I think that code being so abstract it's easy to misunderstand or to just not be able to think about it very easily. And having these parallels in the physical world allows us to understand better that, hey, wait, there's something to be said about that.

When we're writing code, we run into a lot of similar constraints. When we have code that we've just kind of thrown stuff together and allowed it to build over time, which is the easiest way to let things happen, it's kind of how code usually goes. If you're not very conscientious about it, then you end up with a structure that's kind of formed ad hoc, and it gets harder and harder to work with. And it's not just a small thing like superficially hard like, yeah, that's kind of not aesthetically pleasing to me. But it makes it less and less useful.

You accumulate what we call technical debt, which is doing something quickly now that you'll have to pay back later. It can actually accumulate to the point where it's very hard to get anything done because it's really hard to tell when you make a change whether it will have ripple effects somewhere else in the code that's really hard to understand because you can't see it. You can't wrap your head around it. I've got other stories I could tell, but I wanted to start with that one to set the stage for our discussion.

RAMSES: I think you bring up an interesting point; when the code is organized well, it makes it easier to think about and easier to find things. Like, in a pantry that's disorganized, back to your analogy, if it is disorganized, it's hard to find things. And you often buy the same thing even though you already have it, and it's perfectly usable.

MIKE: Oh, I'm thinking about times I've had to navigate messy code and tried to find something. [laughs] I have absolutely seen people rewrite code that does the same thing as what was already there because they couldn't find it.

DAVID: This just reminds me, like when I started coding, there were no standards obviously in the place that I was. So I was just writing code, writing code, at the end, it was working. Six months later, when you have to go back to make a change or something, it was extremely difficult because you probably have forgotten about it. When you take a look at it, it is like, oh my God, who did this? Oh, it was me, but I don't remember now.

MIKE: [laughs]

DAVID: And it's working. But why did I do it in this way? Nowadays, it's, for example, people working in places like Acima, which has standards, we follow our code review process. We guarantee that new code always follows good standards, and it's probably a little bit more easy to organize. That doesn't mean that maybe we're going to switch it later to a team that needs to do delivery faster.

I have also been there on teams that there is one team which has time to build code in a proper way and another team that they just deliver. It doesn't matter how you write it; try to write as good as you can but just write your code and try to do the delivery as fast as the client requests. And as you mentioned, add a ticket to work on this later for the other team, but unfortunately, I think sometimes it adds a little bit more complexity to the code. I believe it's something that we need to avoid.

MIKE: That's interesting, one team that does a bunch and the other team that cleans up. Do you think that that actually ends up going faster in the long run? One team that just tries to go fast, another team cleans up?

DAVID: No, it will definitely add more time to the other team, especially if they need to do a change of something.

MIKE: Yeah, there are some choices that you can make, shortcuts you can take in the code that might save a little time in implementing it in the short term, maybe, but in the long term, make it much slower because it's harder to work with, and sometimes very small changes that have big impacts for years afterward. I believe strongly that taking a little bit more time to do it better upfront usually doesn't take more time.

To share a recent story, I won't go into deep details about the project; there's a team that was trying to get a project done quickly. And they thought, well, this is so urgent. We don't really have the time to coordinate and get all of the names in common, and it's just names, right? Making sure that we're on the same page about what things should be called. We're not going to get all that straight ahead of time because we just need to get going, so we just need to get coding.

And several months later, after implementing it the third time, [laughs] they finally got it out after having coordinated and gotten all the names straight. The process of trying to get things working across teams when they didn't have the contracts well established, and those boundaries well understood meant that they didn't match, and it was kind of a disaster. And doing it the way that should have been done in the first place actually worked. Luckily, we don't have a habit of doing things that way around here. It was anomalous, but it was kind of eye-opening to see that this one project that they tried to rush didn't work. It didn't work. And that's just a single example.

If you build your code that way for years...and I've been in a number of places over time, and I've seen code that just created things on top of the mess, more and more and more, you know, just shovel it onto the pile. It may save a small amount of time upfront, but oftentimes it doesn't even save you time then. It can take more time to try to take the shortcut than to do it the long way. Everybody who has in the real world tried to take a shortcut has likely found that oftentimes the shortcut actually takes longer. [laughs] It works that way in software too. Have you all had that experience?

DAVID: Probably I've mentioned this in other podcasts; I'm not sure. But there was one big function, so big that it takes like, I don't know, hours to finish. It needed to be completed in minutes because we needed to run it at night, so we don't affect any clients. But we needed to do some changes there. The function was extremely confusing to understand, and to fix it that we decided to just drop it and start one from the business side logic and created a new one following good standards.

Once we finished it, from hours to finish, it just took minutes. It still was heavy, but the approach we followed was to just build it from scratch because it was so difficult to understand. There was so much business logic there that it was just better to do it from scratch than to try to fix something that is already too tight.

MIKE: And did you even rebuild it with performance in mind, or did you just rebuild it, and it worked?

DAVID: Oh no, we built it with performance in mind because we took a look at some of the ways they were doing some cycles in the code. And they were performing a lot of queries to the database. Instead of just pulling one amount of records first, work on them, and then pull some other records later, they were just pulling on one record. They had the N+1 problem a lot of times there. So yeah, we thought about performance first.

And we also thought of something which I've mentioned some times in architectural meetings. We thought of building a guide about how this process works because all the business logic was in the code, but it was spread across multiple people. So you have to ask someone from legal, someone from, I don't know, who worked with the clients to know why this process works in this way, someone from another department to know why this process works in this way. So we gathered all that information, and we built some guide first, so we documented everything. And then, we managed to code the version again.

And after we coded in a proper way, there was already a guide and some documentation that you can first read and understand from like a lecture. And then you can go and take a look at the code, and then you'll see, oh, now this makes more sense. So we did those two approaches, which I think was a good approach in order to do that.

MIKE: To talk about refactoring something for performance, I was involved in a project a number of years ago. I was working for a company to build a CMS, a content management, and we had code that would display advertisements. But the CMS we provided was...the company is defunct now, so I could probably talk about it, but it was for primarily newspapers, magazines. The publishers were moving online. And sometimes, they worked with advertisers, so we had to have our own ad network. But mostly, we worked with external ad networks.

But we also had our own in-house ad network at the time so that these publishers could run ads from their local merchants. A car dealership, for example, might want to advertise on the site, and we had support for that. And we noticed that the serving of ads because there were a lot of them on a page, was more than half of all of our database load. And just our overall time in our application, more than half of it, was just serving these ads, which seemed really excessive given that the ads were relatively simple. And there's all the work of publishing the articles and showing all of that content, but the ads ended up dominating that.

So we extracted that code out and just built it from scratch in a really small microservice. It really didn't do very much. It just was very focused on delivering the ads, and that's it. And once we had that built and took it out of the primary app, it went from being most of our database load to being almost unmeasurable; it was just 1% or 2%, I think. It was an insignificant part of our load. Just cleaning it up, just cleaning up the code, and getting it out into its own place where you could see it and think about it made a tremendous difference. And then we basically forgot about it because it just worked.

DAVID: Yeah, that sounds great. I wanted to bring something now that we're talking about cleanliness. I'm not a big fan of unit tests, [laughs] but I know they are pretty good in order to ensure that your code works as expected. And this is something that I found in this process of knowing how to code in a better way. If you find that your unit tests, for us RSpec, if you find that your code is getting a bit more complicated to test, that means that maybe your code is not coded in the proper way, and you're adding more than you need there.

So this is something that I actually use to ensure that I'm writing something that other people can understand and that I'm doing it in a proper way too. Because I've been there that I'm trying to test something that is just not possible to test in the same class, and you know, oh, maybe I need to move this to another class because it's a completely different thing. So yeah, I believe unit tests are a good tool to write better code, clean code.

And I think this is something that here we can do; I mean, we have good examples here because we're being clean in the current RSpec we have writing here in our project. And, I don't know, the other guys can tell me if they have found it, but I have seen some examples where trying to test the code is hard sometimes because maybe we could have done a bit better in the way we did that class or something like that. But yeah, I think it is just amazing to ensure that you are making an easier code or clean code to save some time.

MIKE: I think that's a fantastic point. Well, unit tests have several things that they are good for; sometimes, what their primary value is is not what you think their primary value is, [laughs] I'll put it that way. You think, well, I just want to verify that my code is correct and unit tests are good at that. But if you've thought through your code wrong, you're likely to think through it wrong on your test as well. So you're testing that your code does what you expect it to do, which was not what you should have done in the first place.

Tests can actually be misleading in that regard, but there are some things they're very good at, like allowing you to refactor and make sure your code isn't broken. And what you just said is a tremendous one, I think. It's a tool, an instrument. It gives you visibility into your code quality. If your code is easy to test, then that suggests that it's easy to think about because your tests are kind of like an external observer. And if your code is really easy to test, good on this branch, good on this branch, test both of them, and everything's good, that's a really good sign that your code is good.

And if your code is really hard to test, then you probably have too much going on, right? I'm with you 100%. It's an excellent indicator. Ramses or Eddy, do you have any thoughts about using tests to kind of force yourself to keep your code clean?

EDDY: So I can see the more in-depth I get into picking up tickets and breaking unit testing, I'm starting to see the benefit of why we have them. If you test with QA and unit testing, like, you're ensuring that the ticket or the dev ticket that you picked when you're deploying the master is working the way it's intended. So not only are you testing the code, but you're also testing the UI side of stuff. So I do see the benefit behind it. It can be quite stressful to wrap your head around at first, but I do see the benefits on unit testing for sure.

MIKE: Another thing that got mentioned...I think somebody mentioned it. I think you mentioned it, David, but it may be you just said something that made me think about it, but I think you mentioned it. You talked about, I believe, RuboCop, which is what they call a linter, but it's also a static code analysis tool. We have those across languages that a linter is a tool that checks your code syntax and makes sure that it's clean. Static code analysis goes a little bit further and does some analysis on your code to check whether it has some security vulnerabilities or whether it has some complexity and just some kind of broader tests. And the boundary is a little bit fuzzy between those two.

A really sophisticated linter might start going into some of the static code analysis. And a purely static code analysis tool might actually have some linting built in as well. But these related tools exist in a lot of languages. And I didn't use those early in my career, and now that I do use them, I think that they are fantastic. And I say I didn't use them; I didn't use them as much, I'll say that. I don't think I've ever completely gone without using those kinds of tools, whether your IDE makes them suggestions or I would run...certainly there's compiling where I'd run syntax checks.

Now that these tools are more broadly available, I love them, RuboCop in the Ruby world, because it takes the job of enforcing consistency out of the hands of your peers. So your peers don't have to nag at you and say, "Oh, you forgot to indent here." Instead, you can together come to a standard and usually use a community standard that says, "This is how we're going to do it." And you all agree that you're going to do it that way, and now you don't have to think about it. Now everybody is coding to the same standard.

And, generally, it's enforcing not just arbitrary choices like how far should you indent, resolve the tab versus space arguments [laughs] by just not having them, whatever linter you're using is going to make the choice for you, and you don't have to have the argument. But it goes further than that. It means that because you're not having those disagreements over...I'll come back to the idea of a bike shed. You're not having disagreements over irrelevant things. You can actually talk about relevant things in your reviews.

When you have one of your peers reviewing your code, they are not thinking about how distracted they are by some syntax somewhere because they don't have to. They get to think about structure and whether it actually solves the problems that it's intended to solve, and that's a much better thing to be thinking about. It's much better discussions to be having. They're much more fruitful and likely to lead to better changes than just making some superficial changes.

Coming back to the idea, there's a widespread idea in software about bikeshedding and the idea that, as a verb, you bikeshed. It's a verb. And where that verb comes from is the idea you build something very complicated like a nuclear power plant. People in the community are really not going to share an opinion as to what the design of the reactor is going to be because they don't have the expertise to make that kind of choice. There are going to be a few people who have that expertise who will evaluate the parameters and come to a decision. So it's a very important decision that will have decades-long impact, but only a few people will participate.

But if you build a shed out front to keep bikes dry when people go up to park at the facility, and you ask what color it should be painted, you will have long, maybe months-long arguments and debates of people expressing their opinion as to what color that shed should be painted. And the idea here is that the debate over something is usually inversely proportional to how important it is. The more important a decision is, the less likely it is to be debated.

And linters help with that problem because they remove that lengthy discussion over irrelevant topics. And what colors should be painted? Well, it's always going to be black, and you don't have to make that decision. In the end, that decision didn't matter very much. It frees your mind to talk about the more important things. It's an aspect of code cleanliness, keeping your syntax clean, that I think it's fundamentally important. You can't understand code very well if it's a mess. But you can solve that by using an automated tool to tell you how to do it and then do it that way.

DAVID: Yeah, I totally agree. And I'm glad you brought this up, Mike, about RuboCop. I also have...sorry about that. So when I started coding and I was introduced to RuboCop, I was angry [laughs] because it was highlighting all my errors in the code and, like, who invented RuboCop? I was so angry.

MIKE: [laughs]

DAVID: Of course, I was a junior, and in those times, I was thinking that I was right in the way I was writing code. And then I realized that, no, this is actually a good tool because it provides you a better way to do things. And it also ensures that other people that are going to, which is the most important thing. Also, if other people are going to change your code, at least it follows a standard there. So yeah, it's a pretty good tool.

And this is something that I'm glad that Ruby has, so RuboCop is one of those. And I also wanted to mention another one which is Rails best practices, which also allows you to follow good practices in Rails. So this is just great in order to talk about important topics, as you mentioned, in your code and not only maybe the way you just coded something. A tool is already going to provide you with a fix, with highlighting the error and using it in a proper way. So yeah, I'm glad we use those tools here in Acima.

MIKE: You know, some languages, you can take languages with syntactic whitespace like Python, for example, they structure the whole language to enforce certain conventions. So you can't argue with it. Your code won't work unless you write it cleanly. And it doesn't solve all problems, but it does solve some. And there are proponents and detractors of that idea out there; not everybody loves it.

But there's a reason that people would have that idea and push it forward because it's just so important to have that consistent syntax to be able to work together as a team that it's worth having it baked in the language where you can't even get your code to run unless you follow that standard. There's a reason that people would build something that way, whether or not you think that you should do it that way. It suggests that there's enough value that some people have considered doing it that way.

DAVID: Yeah, definitely. And this also saves time. And I wanted to mention this because last time we had our weekly meeting, we mentioned that no one is going to code review your code if you don't ensure that RuboCop passes. [laughs] And it's something good because it is our team's standard. And it also ensures that you're going to present some code that follows the team standard and follows the rules that RuboCop currently has. So this is something really good.

MIKE: I agree with you on that. If you're not used to doing it that way, it can sound like, wow, that's a pretty strict rule. You won't even review my code if it doesn't have clean syntax? I'd say the opposite is true. If you don't have a rule like that, then you're forcing the reviewer to have to make comments like, "I don't like the way this is structured. It doesn't really follow the standards." You are coercing your peer into evaluating parts of your code that it shouldn't be their job to have to review.

Why should they have to enforce community standards when that can be automated? It's kind of silly and, arguably, kind of rude that you would ask somebody else to do work that you could have automated. It's part of, I think, taking pride in your code, being a craftsperson to be willing to just take that little extra time to make sure that you follow the standards.

DAVID: I agree. A few years ago, we didn't implement this RuboCop in one of our projects, and we, the devs, spent a lot of time just trying to have our team standards like, hey, make a breakpoint here; this is a new line. And oh no, do an end instead of curly brackets here. And all that time could have been saved if we had used RuboCop. Because we used to have like 20 comments per code review [laughs], and that was just a lot, something that RuboCop could have just fixed in a couple of minutes or seconds, actually.

MIKE: And you can integrate that into your editor, and then you don't even think about it. Because you get syntax highlighting that says, "Your code is not following the standard here." I learned to see from a long way off in my editor; oh, I know exactly what's going on there. It's just got the underline or the color saying something is going on here.

I know, even without having hovered over to see what the message is, I know exactly what the problem is. Because, like, oh yeah, I bet that that's saying I haven't added a comment on my class to say what it does, or I bet that's saying my line is too long. So you end up internalizing it to where you do it without even thinking about it, which is great.

So let's see, we've talked about how messy code takes longer to work with and may not even save you time to make the mess in the first place. We have talked about the value of following standards. We've talked about the value of sometimes refactoring and starting over from scratch and building something clean because it saves you more time than trying to fix code that is so messy that it is unsalvageable.

I think there are some other interesting questions here. One interesting one, I think, is how do you start a project clean? How do you start it with standards such that you avoid a lot of these problems upfront? You're never going to avoid all the problems. Just by natural growth, I think any system is going to develop parts that are more complex than other parts. And in that natural progression, you'll notice that this part has become more complex than it was initially, and I need to go in and refactor it.

So I don't think you can universally avoid problems, and just naturally, some things are going to be more complex than others. However, I do think that you can avoid a lot of the worst pitfalls by starting off with good standards and good structure. I have some thoughts on this, but I'm curious what you all think.

EDDY: I like the idea of clean code; for example, the concept of self-documenting code is really important, especially to me when I'm viewing a file for the first time. And I think that the code should be describing what the code intends to do by itself without the need of following the syntax per se. I think the Ruby syntax really aids in that as well because it reads in English. But having the code do the talk for you is really important.

MIKE: That's interesting. We've talked about things we can use to measure whether the code is good or not. Like you say, if you read the code and it looks like English and reads like prose, the code itself reads like documentation, that's a good sign that it's well-organized and easy to understand. And if you have to stop and think about it or if you have to have a lot of comments to explain it, maybe you've done it in a way that is not easily thought about, and it'd be better to reorganize that.

As David was saying, that person that comes back and doesn't understand it is likely to be you six months from now or maybe one month from now sometimes. [laughs] Future you is not going to remember current you very well. And it's going to come and try to figure out what current you is doing and wish that you had been more conscientious.

EDDY: Or having easy-to-understand names, [laughs] like, that's really, really, really important.

MIKE: I think we could have a whole session on that one. I think it's funny that, as developers, we'll sometimes think we're saving time by dropping a few characters in a variable name, like, oh, I'm not going to put these characters in there because I want to save those three characters of typing, which takes you some fraction of a second. But then, when you come back and try to think about the problem, you have to figure out what that variable name is, and it takes you several seconds every time you look at it. What time have you saved?

I think you almost never save time by coming up with abbreviations because they force you to have to think more about it. And that thinking about it takes a lot more time than the trivial amount of time it takes to type a couple more characters. I mean, we've got good tools for input. Even if you have some, you know, I sometimes get some repetitive stress of it, and I don't want to be banging away on the keyboard all the time. And despite that, I think variable names should be long because it just doesn't add very much to write a few more characters to make your names easy to read.

And yeah, to ask my question that I was asking before a little bit again, how do you get the standards from the beginning? I could make some suggestion there that, in most cases, it makes sense to go with some sort of community framework rather than thinking I'm just going to start things from scratch and put it together as it goes. I want it to grow organically. Well, okay, things do grow organically, but people who garden put up a trellis for their climbing vines because they want to give them an opportunity to grow and not just sprawl out across the ground.

This idea that things growing should not be restricted at all, I think, is misguided. Things grow better when given an opportunity to climb up a structure toward the sky. And if we give them that structure, to begin with, then things will grow organically to fill in the space that you're providing for them. And if you don't provide them that space, then they'll hit those constraints very quickly. And you're going to have to rebuild it, and rebuild it, and rebuild it, and create those constraints over time, which is much harder than adding some constraints up front.

And specifically, I think it makes sense to say, well, this is where these kinds of files go. In some languages, you're not going to have as much opportunity there. But almost everything you're going to work in is going to have some sort of framework, and then you can think about architecture. Well, what if I'm going to use model–view–controller architecture? So I'm going to have my data layer over here, and I'm going to have my logic layer here. And I got my presentation layer over here.

Taking the time upfront to separate those ideas, to separate that code, and organize it is worth it. It is absolutely worth it, and that's why frameworks are popular. Also, they do a lot of the lifting for you. But the convention, the code conventions, this is where you put things is sometimes underappreciated as a vital part of what those frameworks provide you. It's not just the libraries they provide, which are invaluable, but it's also the structure.

DAVID: I totally agree with that. I've tried to create a few projects in the last few months just for fun. So I like the fact that when you're going to start a new project, the language itself or the framework itself provides you with the tools as you manage your code better. I don't want to start to go into details, but, for example, with React, if you try to use React, sometimes they enable the ESLint; I think maybe it is called.

So if you make some syntax errors or just code in some weird way, it will highlight the error, and your code won't compile, [laughs] and that's good. You probably get a little frustrated at the beginning, and then you'll be glad that it highlighted that error because it will definitely save you in the future.

In the case of Ruby, I do agree that when you're going to start a Ruby or a Ruby on Rails project, you should add these valuable gems we talked about, like RuboCop is one of them. Bullet is another one which will highlight the N+1 error or how your queries are in the database. So yeah, I think that's a good approach; use everything that frameworks provide in order to code better and clean.

MIKE: I'm with you. [laughs] Bullet is a nice tool. As you say, it looks for things you do with the database that you shouldn't. [laughs]

DAVID: Yeah, it has saved me sometimes, [laughs] a lot of times to be honest.

MIKE: Great. I think that we're reaching the end here, the time we were going to spend. Does anybody have any final thoughts that they've been holding in they'd like to share about code cleanliness and organization?

DAVID: I just wanted to close that having team standards is extremely valuable in projects because they let you grow up as a developer and also as a person because you will understand the way the team works and the way you should also think if you go into that team. That also provides or gives you a way of knowing how mature a team is. And here in Acima, it's something that we actually have.

We have changed our standards too. I mean, we have had a few meetings where we'll talk about why we changed this in this other way. And we come to an agreement, and if it is good for our team, we change it. And so this is something great that a team should have. And it is something that is so valuable because it will help you code better. It will help you understand more the way to code and also the way the team works. I just want to highlight that. I'll finish with that line.

MIKE: Again, you said it wonderfully. Those team standards just make such a difference. Maybe I conclude here by tying back to where we started, the idea of organization. And I say we should all be more like my wife [laughs] and treat organization not just as an aesthetic concern, like, I like the way this looks, but realize that it's a fundamental characteristic of something that is easy to use, and that is maintainable in the long term.

Take some time to learn some of that science of some of the process that is involved in creating good structure, good hygiene, good cleanliness in our code so that we can maintain our software into the future. Take the time to develop those team standards because it's worth it. It's been great talking, and I'll see you next time on our Acima Development Podcast.