[MUSIC] Refactoring goes hand in hand with another concept that we've talked about, and that's regression testing. So if we're going to go and take our current software state or component A, and we're going to refactor it to maybe be broken up into a couple of pieces that are more modular and allow us to plug in different implementations. And we go and begin changing our code. One of the basic things we want to do is we want to make sure when we refactor our code in an attempt to improve some nonfunctional property, that our change doesn't end up breaking the existing code. So if we refactor and then regress in some other part of our system, that's a problem. So one of the important concepts of refactoring is that we refactor code and then we regression test code. So when we go and make changes to try to improve the code, we make sure and we regression test it to know that the changes that we're making aren't going to break something that already existed. And in many cases, when we're doing refactorings, we are going to break other things in the code. We're going to change how our design works, we're going to change some aspect of our code that is going to break other things in our code. And so refactoring is important, not only to make sure that when we're done with the refactoring that we don't have any lurking problems that we haven't discovered. But also it's a tool to help us understand, when we begin doing our refactoring, what are all the other ramifications that we need to go and also fix? So sometimes we may say, and I just changed the design of this class slightly. It's not going to affect anything else. But it'll greatly improve performance. But then when you go and actually make that change, you realize it breaks other things. And you have to go and begin changing assumptions in other places. So part of refactoring is being a good citizen and regression testing what you're doing in order to, one, know that you haven't broken anything existing. But also to know what are the other things that this code relies on that also need to be changed after the refactoring. So it's a way of knowing where we are, it's measuring, as we talked about over and over again, the changes that we're making and their impact on our code base. Now if we don't have regression tests, we run into the problem, if we don't have a robust test suite to run regression tests, then we end up in the place where we have code that works. We know it works, and we've become scared to refactor it and improve it because if we make a change, we don't know if we've broken something else. So the fewer tests we have, the less confidence that we have in our test suite, the more fearful we become of performing refactorings in order to improve the non-functional properties of our code. And this can be a liability to our software development process. Because if we don't feel like we can go in and easily make changes to code that we know will improve the non-functional properties, Then we become reluctant to make them. And what happens is, over time, we have code that we know is bad, but it's working correctly, so we don't want to touch it. And we end up with a culture of, let's not improve the state of our house, because it may fall down if we change something. So we want to have a robust test suite, so that we always feel confident going and improving the nonfunctional properties by applying refactorings. We never want to feel like we can't touch anything, because it's so brittle, it's so broken, and nobody knows what's going to happen if we make a change. That's not a maintainable software product, that's not where we want to be. So regression test and refactoring, they go hand in hand. Being able to know that when we make changes to improve non-functional properties, we're not breaking other things. To build that confidence in our developers that it's okay to refactor things for reasons other than functional attributes. That's one of the reasons why we want to build robust test suites. And that's one of that we want to do refactoring, is to continually improve the nonfunctional aspects of our software.