Latest / DevQuestions with Tim Corey / 257. Why Do Old Codebases Look So Bad?
Transcript
- 0:00SPEAKER_01: It's your first day at a new job, and you open up the code of the project you're working on for probably the rest of your career.
- 0:07SPEAKER_01: This is a major application that runs your new company.
- 0:10SPEAKER_01: After spending some time looking at the code, you realize that it's a mess.
- 0:15SPEAKER_01: There are issues all over.
- 0:17SPEAKER_01: In fact, when you open up the queue of work to be done, you see a huge list of bugs to be fixed.
- 0:23SPEAKER_01: The code has obvious formatting issues, the naming conventions aren't followed everywhere, and there seems to be a dozen different things wrong that you can spot in the first hour or two of review.
- 0:34SPEAKER_01: Why is this?
- 0:36SPEAKER_01: Is it just that you picked a bad company to work for?
- 0:39SPEAKER_01: Are the previous developers just bad at their jobs?
- 0:42SPEAKER_01: I think there's more to it than that.
- 0:44SPEAKER_01: Even though we have solid, dry, and a host of other design patterns and principles to help us write good, clean code, somehow that doesn't seem to translate into long-term production apps of any size.
- 0:58SPEAKER_01: Yes, there are some apps out there that are great, but they seem to be the exception rather than the rule.
- 1:04SPEAKER_01: So in this DevQuestions episode, we're going to talk about why legacy projects are messy and how we can avoid them in both our new projects as well as make our messy projects better.
- 1:28SPEAKER_01: Software development is more than just writing code.
- 1:31SPEAKER_01: So let's talk about the rest of it.
- 1:33SPEAKER_01: Specifically, let's talk about why legacy software development projects are almost always messy.
- 1:40SPEAKER_01: I think we can all agree that most projects start with the best of intentions.
- 1:44SPEAKER_01: We have high hopes for how we'll design the project and how we'll execute on that design.
- 1:50SPEAKER_01: So, where is the disconnect?
- 1:52SPEAKER_01: Why do projects fail to live up to their aspirations?
- 1:56SPEAKER_01: I think there are five major reasons that I'll come back to one principle.
- 2:02SPEAKER_01: So let's talk about the five major reasons, and then we'll talk about that one principle.
- 2:06SPEAKER_01: Reason number one is probably an obvious one if you ever worked in corporate, and that is developers don't have enough time.
- 2:14SPEAKER_01: When you are working on a project, you don't have this infinite deadline.
- 2:19SPEAKER_01: In fact, if you did, it's probably actually a bad thing.
- 2:21SPEAKER_01: But developers never seem to have enough time to get the job done.
- 2:26SPEAKER_01: Instead, they're rushing to deadlines.
- 2:28SPEAKER_01: They're rushing to get the new feature out the door, they're rushing to get those bug fixes in place before the customers burn down the place.
- 2:36SPEAKER_01: They're rushing to get things done.
- 2:38SPEAKER_01: When you don't have enough time, you cut corners.
- 2:42SPEAKER_01: When you don't have enough time, you don't do cleanup.
- 2:45SPEAKER_01: When you don't have enough time, good enough is good enough.
- 2:49SPEAKER_01: And that's not always wrong.
- 2:51SPEAKER_01: In fact, a lot of times that can be right.
- 2:54SPEAKER_01: But that's one of the reasons why your code is gonna be a bit of a mess because the developers didn't have enough time to do it the way they would have liked to have done it.
- 3:06SPEAKER_01: So that's number one.
- 3:07SPEAKER_01: Number two, designs are never perfect.
- 3:10SPEAKER_01: We're missing things in designs.
- 3:13SPEAKER_01: So you design this system the way you think it should work.
- 3:16SPEAKER_01: Let's even make it even easier.
- 3:18SPEAKER_01: Maybe you already have a system in place and you're going to rewrite.
- 3:22SPEAKER_01: And this is like the dream of a software developer.
- 3:26SPEAKER_01: You're you're 10, 15 years into a project and you go, man, we've made so many problems, so many mistakes in this application.
- 3:32SPEAKER_01: I would love to go back to square one and start over.
- 3:35SPEAKER_01: I've learned so much.
- 3:36SPEAKER_01: I know we could make this app so much better if we started from the ground up.
- 3:42SPEAKER_01: And quite frankly, that's not gonna happen.
- 3:44SPEAKER_01: Because even though you might start from the ground up, even with all the knowledge you have, your designs are never going to be perfect.
- 3:52SPEAKER_01: You're always gonna miss something.
- 3:54SPEAKER_01: You're always gonna forget about something, you're always going to have a new circumstance that changes how the system is going to work, which means that you're going to have to change your code after it's written.
- 4:07SPEAKER_01: And that's where things get really messy.
- 4:09SPEAKER_01: When you architect for a very specific way of doing things, and then you find out that's not the right way, you have to make changes.
- 4:17SPEAKER_01: Well, it makes things messier.
- 4:19SPEAKER_01: Think about building a house.
- 4:21SPEAKER_01: Maybe you have the perfect design for a house.
- 4:23SPEAKER_01: And you you bit you start building this house and you have all the framing in place for all the different rooms and how they're gonna lay out, and you realize ah, the bathroom is in the wrong spot.
- 4:34SPEAKER_01: We need to move it.
- 4:35SPEAKER_01: Well, think about that.
- 4:36SPEAKER_01: If you already have the framing up, if if the house is already starting built, how much work does it take to move a bathroom?
- 4:45SPEAKER_01: Quite a bit.
- 4:46SPEAKER_01: You have to move the actual structure.
- 4:48SPEAKER_01: You have to move walls and change things around, rip things out, change how uh things are laid out, change load-bearing walls and all the rest.
- 4:55SPEAKER_01: And then you have to move plumbing and you have to potentially change your foundation, dig things up, and change your electrical and so many other things because you've already started building.
- 5:05SPEAKER_01: The same is true for applications.
- 5:07SPEAKER_01: Your design may not have been perfect.
- 5:10SPEAKER_01: And when you start to build the house, your application, you have things in place, and then you find out, oops, we have to make a change.
- 5:20SPEAKER_01: Well, that means ripping things out and putting things in new places and doing things different ways and overloading things, and now you have things, you know, methods that are not being used anymore, or partially used, or that have been changed dramatically from what the original the thought was, and now things are named improperly, but they work.
- 5:38SPEAKER_01: So many other things come from designs that aren't perfect because no design ever is.
- 5:45SPEAKER_01: Now, number three, designs aren't set in stone.
- 5:49SPEAKER_01: So even if, and it's not gonna happen, but even if you have the perfect design and you design the perfect application and you're building that perfect application towards the perfect design.
- 6:00SPEAKER_01: Again, never gonna happen, but let's say you did.
- 6:02SPEAKER_01: Does that mean you will never have to change anything?
- 6:06SPEAKER_01: Well, no, because guess what?
- 6:08SPEAKER_01: The the boss comes along and says, hey, I know we said they were only ever gonna have a maximum of four people in a car, but ah, we have this one case where we need to have 10 people in a car.
- 6:22SPEAKER_01: And you're like, I architected for four.
- 6:24SPEAKER_01: I even had carryover, I said I said six because I thought maybe we want to exceed that once in a while, but I didn't expect 10.
- 6:32SPEAKER_01: Well, the same thing is true in your code, right?
- 6:34SPEAKER_01: You you might design for a certain circumstance that changes down the road.
- 6:40SPEAKER_01: Um, the way a feature might work is going to be different.
- 6:43SPEAKER_01: And so even though you have the design in place, that design will change at some point.
- 6:50SPEAKER_01: And the worst part is it's not going to change in the design phase.
- 6:54SPEAKER_01: And it might, but it's not going to just change in the design phase.
- 6:58SPEAKER_01: What could happen is, what will happen is that as you start building, maybe even getting ready to launch the application or launch the feature, whatever it is, you're going to get changes.
- 7:09SPEAKER_01: Or maybe it's in production for a while and it's gathering information, you're capturing information, and then you find out, oh, we need to change things.
- 7:16SPEAKER_01: Maybe you are capturing just first name and email address.
- 7:20SPEAKER_01: It's all you needed.
- 7:20SPEAKER_01: The boss says, we just need first name and email address so we can email people and say, Hi, Tim, that's all we need, right?
- 7:27SPEAKER_01: So you build that system.
- 7:29SPEAKER_01: But then a month or a year down the road, the marketing says, we actually need their last name too, so we can start doing lineups of billing, and we need to make sure that we also capture their country code.
- 7:43SPEAKER_01: Well, okay, that's a change.
- 7:45SPEAKER_01: And you can change the form, but not only is it not gonna, it's not gonna backdate all those other forms that have been filled out.
- 7:53SPEAKER_01: So now you have hundreds, thousands, tens of thousands of records with first name and email address, but not country code and not last name.
- 8:02SPEAKER_01: So now you have a messy situation, which means your code will also have to reflect that.
- 8:07SPEAKER_01: Your code will have to take into account the idea that, yes, last name is now required, but we can't assume that it's going to be populated.
- 8:15SPEAKER_01: Therefore, we have to say, hey, if last name is null, then do this.
- 8:19SPEAKER_01: That's extra code and extra workarounds for the legacy decisions.
- 8:26SPEAKER_01: So those kind of things are going to make changes and make your application a bit more messy.
- 8:31SPEAKER_01: Number four, your assumptions can be wrong.
- 8:35SPEAKER_01: You can assume certain things, and every application has assumptions.
- 8:41SPEAKER_01: But you're not always right.
- 8:42SPEAKER_01: Sometimes you make the wrong assumption and you make a decision based upon that assumption, and you don't even figure out that it's an assumption, let alone a wrong assumption, until it's too late.
- 8:53SPEAKER_01: Where you find out, oh, I assumed that every person would have a first and last name.
- 8:59SPEAKER_01: Well, that might not be true.
- 9:00SPEAKER_01: And so what do you do in that case?
- 9:02SPEAKER_01: Okay, you have to make a change or make make some adjustments.
- 9:05SPEAKER_01: Maybe if if you had first and last name locked in as required, not null, and all the rest, but now you find out that some people don't have a first or last name, well, you have to go unlock all those not nulls to be nullable, or you have to put in there a placeholder for the first or last name, but then wipe that back out.
- 9:25SPEAKER_01: Like it, it gets messy, right?
- 9:27SPEAKER_01: Because you had an assumption.
- 9:29SPEAKER_01: And you may not have realized that you were assuming every person has two names, but that could have been an assumption that was wrong.
- 9:37SPEAKER_01: Okay, number five.
- 9:39SPEAKER_01: External systems and dependencies change over time.
- 9:43SPEAKER_01: This is a big one.
- 9:44SPEAKER_01: Okay, so even if your application was built great and it was built to spec and and the spec was right and you didn't have any assumptions and nothing ever changed afterwards.
- 9:58SPEAKER_01: So you have taken care of all of your things you can control, all the internal stuff, including marketing and sales and all other people.
- 10:06SPEAKER_01: You control all of that and say, you know what?
- 10:08SPEAKER_01: No, this is the application you get, it's never gonna change, which is a fantasy.
- 10:12SPEAKER_01: But let's just go with that.
- 10:14SPEAKER_01: Even if all of that's true, you're still gonna have to deal with new servers, new ways of doing things in Azure, or wherever you're hosting your application, um, new third-party dependency changes.
- 10:28SPEAKER_01: For example, um it used to be that websites would be HTTP, and then if you wanted to do anything secure, you would change over to HTTPS.
- 10:38SPEAKER_01: Well, at some point, Google came along and said, no, you know what?
- 10:41SPEAKER_01: We want HTTPS for everything.
- 10:44SPEAKER_01: So all the applications that had been built upon using HTTP primarily and just HTTPS for secure transactional things, all of a sudden they had to change, not because of anything they did, but because of an external source.
- 11:02SPEAKER_01: Google said, you're gonna do this and basically forced the rest of the world.
- 11:07SPEAKER_01: Now it's a good choice, but they forced the rest of the world to change.
- 11:11SPEAKER_01: The same thing is true with Microsoft Silverlight.
- 11:13SPEAKER_01: People love to say, oh, Microsoft abandoned Silverlight.
- 11:16SPEAKER_01: Not quite the story.
- 11:17SPEAKER_01: We've got a whole video on that.
- 11:18SPEAKER_01: But what happened was Steve Jobs said, we're not gonna allow these third-party applications access to the iPad.
- 11:27SPEAKER_01: And all of a sudden, they took away a lot of the latitude that browser plugins had to make changes and do things on devices.
- 11:39SPEAKER_01: And really, the the target was Adobe, but the the fallout from that also attacked Silverlight.
- 11:47SPEAKER_01: Well, guess what?
- 11:48SPEAKER_01: If you are a Silverlight developer building a Silverlight application, your application may have been perfect, but it doesn't matter.
- 11:55SPEAKER_01: It was killed by circumstances.
- 11:57SPEAKER_01: It was killed by Apple and Steve Jobs, and eventually Microsoft because of that.
- 12:02SPEAKER_01: Now, just to be clear, Microsoft supported that up until 2024.
- 12:07SPEAKER_01: But still, that was something where you didn't have to make any changes.
- 12:12SPEAKER_01: Your system could have been quote unquote perfect and never changing, and yet you had to make a big change because the system you depended on, the third-party dependency, changed.
- 12:24SPEAKER_01: So those are the five things that I see are the major issues, the major reasons why code bases are messy.
- 12:32SPEAKER_01: Because all these things cause us to change our code, to cause us to hurry up when we are making those changes, to rip things out and put things in new places that we didn't expect to originally, and so many other things.
- 12:45SPEAKER_01: But they all boil down to one principle.
- 12:48SPEAKER_01: And the principle is the real world is messy.
- 12:53SPEAKER_01: If you can grasp that, the concept that the real world is messy, you can go a long way.
- 13:00SPEAKER_01: So are we doomed to always have a messy code base because the real world is messy?
- 13:05SPEAKER_01: Well, yes, but also no.
- 13:08SPEAKER_01: Okay?
- 13:09SPEAKER_01: So you're always going to have areas that are messy.
- 13:12SPEAKER_01: You're always gonna have to rip things out and change things and move things around.
- 13:15SPEAKER_01: That's inevitable because the real world is messy.
- 13:19SPEAKER_01: But you don't have to give up on your idea of a clean code base entirely.
- 13:24SPEAKER_01: Just be realistic about it.
- 13:26SPEAKER_01: A rewrite with the knowledge you have now isn't the solution.
- 13:31SPEAKER_01: Because again, it doesn't matter if you have the perfect structure for your design.
- 13:36SPEAKER_01: It doesn't matter if you have the knowledge of all that came before and you you know what goes on in your organization.
- 13:42SPEAKER_01: It doesn't matter if right now you know exactly how the application should work, because it's not going to be the same tomorrow or the next day.
- 13:52SPEAKER_01: The third-party dependencies aren't really the same tomorrow or the next day.
- 13:56SPEAKER_01: So rewriting the application isn't the solution.
- 14:00SPEAKER_01: Instead, there are things you can do to set yourself up for success now, whether you're just starting out with a new app or whether you are maintaining a legacy application.
- 14:10SPEAKER_01: So let's go over those.
- 14:11SPEAKER_01: Number one, maintain good coding standards and force them.
- 14:16SPEAKER_01: Okay.
- 14:17SPEAKER_01: So when you are setting out to work on a project, whether it is a brand new application, it's you know the latest and greatest.net, and you're you're starting out with everything clean, it's called a green field application.
- 14:31SPEAKER_01: If you're starting there, that's great.
- 14:33SPEAKER_01: Have good coding standards in place and forced.
- 14:37SPEAKER_01: But if you're in what's called a brown field application, one where it's existing, it's been around for six months or six years or 60 years, doesn't really matter.
- 14:48SPEAKER_01: Even there, you need to identify good coding standards and force them, even if they have not been enforced previously.
- 14:57SPEAKER_01: So that's number one.
- 14:58SPEAKER_01: Have a plan for what good coding standards look like and make sure you enforce them.
- 15:03SPEAKER_01: And that means things like when you do pull requests, you're probably doing pull requests, right?
- 15:08SPEAKER_01: You're making sure you do code reviews on those pull requests and making sure you're looking over what each other does to make sure you keep up to those standards.
- 15:16SPEAKER_01: Please do that.
- 15:17SPEAKER_01: But when you're doing that, you can have something to look at and say, hey, this doesn't follow that standard.
- 15:23SPEAKER_01: Number two, plan time in the budget for improvements every time you change code.
- 15:30SPEAKER_01: My recommendation here is 10%.
- 15:32SPEAKER_01: So it's not a big thing, but it's something, right?
- 15:36SPEAKER_01: So every time you have a new feature you're gonna add or a new bug to fix, put in there 10% of your time is going to be making things better.
- 15:47SPEAKER_01: What I mean by that is let's say you're gonna fix a bug.
- 15:51SPEAKER_01: And you know the method to go into to fix this bug, you're gonna have it change five or ten lines.
- 15:57SPEAKER_01: And when you change those five or ten lines, maybe you put some good logging in or something else.
- 16:02SPEAKER_01: That's not even what I'm talking about when I say plan time a budget for improvements.
- 16:06SPEAKER_01: What I'm saying is, okay, you put that logging in, but maybe also write a unit test for that method.
- 16:12SPEAKER_01: Or write a unit test for that method and put logging in a couple other places in that same class.
- 16:18SPEAKER_01: Okay?
- 16:19SPEAKER_01: So maybe change some naming to make sure it conforms to your standard.
- 16:24SPEAKER_01: Start doing little cleanup things.
- 16:26SPEAKER_01: I like to go to uh parks in the area.
- 16:29SPEAKER_01: We have we have small little parks in Texas where you know it's it's not very big, but there's a lake there, or there's some trails there, something like that.
- 16:37SPEAKER_01: And it's always distressing to me when I see people have just poured a bunch of garbage on the ground.
- 16:43SPEAKER_01: Well, that can be overwhelming because there's so much on the ground and it's I'm just one person and I don't want to spend days and days and days cleaning up the park.
- 16:52SPEAKER_01: But what I can do is when I go there to hang out, take pictures, or whatever I'm doing, I can pick up a few things on my way out and throw them away correctly.
- 17:02SPEAKER_01: That's not going to solve the entire problem.
- 17:05SPEAKER_01: That's not going to fix the entire park, but it's going to leave it a little better than I found it.
- 17:10SPEAKER_01: It's the Boy Scout principle.
- 17:12SPEAKER_01: So that's number two.
- 17:14SPEAKER_01: Number three is to prioritize good fixes over quick fixes.
- 17:20SPEAKER_01: And this takes management's buy-in.
- 17:23SPEAKER_01: So when you have bugs, especially if they're bugs in production, the overriding thing that's going to drive a lot of these things is speed.
- 17:33SPEAKER_01: Fix this now.
- 17:35SPEAKER_01: You're going to have management from up high saying, I want this fixed now.
- 17:40SPEAKER_01: And that can be overwhelming.
- 17:44SPEAKER_01: That can be terrifying in some cases because you've got people looking over your shoulder saying, you need to do this right now.
- 17:53SPEAKER_01: And if you're not careful, or if your management doesn't back you, then what you end up doing is doing quick fixes.
- 18:01SPEAKER_01: Things that will work.
- 18:02SPEAKER_01: It's a band-aid on the problem, but it doesn't really solve the problem entirely, or it's not well-written code, but it's working code.
- 18:12SPEAKER_01: Okay?
- 18:12SPEAKER_01: So what you want to do is prioritizing good fixes over quick fixes.
- 18:18SPEAKER_01: Talk to management, get buy-in.
- 18:20SPEAKER_01: Shit, send in this video and say, watch number three.
- 18:23SPEAKER_01: It's important.
- 18:24SPEAKER_01: But you want to get these good fixes, not just quick fixes, because when you have a code base full of band-aid fixes, eventually it collapses.
- 18:34SPEAKER_01: It might not collapse the entire application, the entire application won't stop working, probably.
- 18:39SPEAKER_01: But what you'll have is slowdowns, you'll have more bugs than usual.
- 18:43SPEAKER_01: You'll start to grind to a halt because of the fact that there's so many things that are leaky, and you just put band-aids over them, and it's not really the ultimate solution.
- 18:55SPEAKER_01: So good fixes over quick fixes.
- 18:58SPEAKER_01: Number four is to continue to improve your skills with writing clean code.
- 19:04SPEAKER_01: This is on you as a developer.
- 19:06SPEAKER_01: You want to continue to make strides in writing better code, writing cleaner code.
- 19:14SPEAKER_01: And that what I mean by that is code that is easier to read, easier to maintain, that's less bug prone, that is better monitored and controlled, that's better tested, so that you can ensure that you're less likely to come back to that same spot to fix that code.
- 19:32SPEAKER_01: So the more you practice that, the more you improve your skills, you can bring that into your code base and start to make those slow, gradual changes to make it better and better.
- 19:44SPEAKER_01: If your code base has zero tests and you learn how to write tests, and you learn how tests can make you better, make your code safer, and you can learn how your code can be easier to change because you can be more confident in that that the change worked.
- 20:02SPEAKER_01: Well, it can be overwhelming when you have a code base of one, two, three million lines of code and zero tests.
- 20:10SPEAKER_01: And you might think, well, I could never write a test suite for this application.
- 20:13SPEAKER_01: You don't have to.
- 20:14SPEAKER_01: Write one test.
- 20:16SPEAKER_01: Write one test, then two, and then a third.
- 20:19SPEAKER_01: And you don't have to do it all at once.
- 20:21SPEAKER_01: Again, coming back to that principle of 10%.
- 20:24SPEAKER_01: You know, just doing 10% better things.
- 20:27SPEAKER_01: Well, if as you continue to improve as a developer and you pick up more and more of these skills for how to write better and better, cleaner and cleaner code, safer and safer code, well, you can start implementing them little by little into your code base and help your team do the same.
- 20:43SPEAKER_01: Number five is to focus on clarity rather than segmentation.
- 20:48SPEAKER_01: This is one that when you're first starting out, especially, you see things like microservices and you look at solid, and the first thing is separation, you know, and the idea of trying to create little things and have tons and tons, hundreds and thousands and thousands of methods and different applications and calls here and there and all over, and your call stacks are 50, you know, 100 levels deep because of the fact that you've segmented out everything.
- 21:18SPEAKER_01: That can be good, but more likely it's actually going to cause you problems.
- 21:22SPEAKER_01: So focus on clarity rather than just segmentation.
- 21:26SPEAKER_01: So it may be that clarity is adding some segmentation, adding some separation of concerns.
- 21:34SPEAKER_01: But it may be that you need to put a couple of things in the same location because they actually are better off just being together.
- 21:43SPEAKER_01: And it makes for more readable code, more maintainable code.
- 21:47SPEAKER_01: And that's the ultimate goal here, not just the ideal, in quotes, um, of what an application could be.
- 21:56SPEAKER_01: So that's the five ways to help you improve your application development, whether it be a new application or upgrading a messy legacy app.
- 22:08SPEAKER_01: Now, a perfect app wouldn't do well in the real world because the real world, it's not perfect, and neither are you.
- 22:17SPEAKER_01: Okay, so you're not perfect, therefore you aren't gonna write a perfect application.
- 22:21SPEAKER_01: Even if you did, the world's not perfect, therefore it won't work well in the real world.
- 22:27SPEAKER_01: Instead, learn to do your best, make the best decision you can make at every step along the way, and then understand that perfection is not the goal.
- 22:37SPEAKER_01: And you may find that as you go along and do that, that as you get more and more experienced, you'll start to realize that the people you are grumbling about, you're the previous developers who worked on an application that you thought was a mess, you start to empathize, you start to realize, oh, they had some good reasons for doing these things.
- 22:57SPEAKER_01: And yes, there can be better ways of doing this, but maybe it's a little too hard on them because I understand now the decision-making process they went through and realize that there wasn't a perfect solution, and they try to do the best they could.
- 23:11SPEAKER_01: All right.
- 23:12SPEAKER_01: So empathize with those who came before you, but learn how to do it a little better every day.
- 23:18SPEAKER_01: All right.
- 23:18SPEAKER_01: Thanks for listening.
- 23:19SPEAKER_01: And as always, I am Tim Corey.
- 23:22SPEAKER_00: Thank you for joining us for this episode of Dev Questions.
- 23:25SPEAKER_00: When you're ready to learn to think and code like a professional developer, head over to IamtimCorey.com and enroll in a course.