So, why bother with a specific term for this type of modifying code? Isn't all modifying code simply modifying code? A systematic approach to the different types of editing and writing code allows us to focus on the side-effects we're expecting as a result of changing the code. Making a change that includes fixing a bug, refactoring, and adding a feature means that if something doesn't work then we're unsure which of our edits caused the problem. The problem could be that we didn't fix the bug correctly, that there was a problem with our refactoring, or that we didn't add the feature properly. Then there's the possibility that one of the edits interacted with the other. If we do encounter an adverse side-effect (also known as, "a bug") in this process, we have an overly large combination of possible causes to evaluate.
It's much easier to focus on one type of task at a time. Make a bug fix, validate the bug fix didn’t cause any expected side-effects. When we're sure that the bug fix works, we move on to adding new functionality. If there are unexpected side-effects while we're adding new functionality, we know that the side-effect was caused either by the code that we have just added to implement the new feature, or the way that code interacts with the rest of the system. Once we know the new functionality is working correctly, we can reorganize the code through refactoring. If we encounter any unexpected side-effects through the refactoring, then we know that the problem comes from either the code that was refactored or some way that the refactored code interacts with the rest of the system further minimizing the domain in which the unexpected side-effect could exist. This systematic approach reduces the time and work involved in writing software.
It's rare as software designers and programmers that we know at the start of a project exactly what the end-user requires. Requirements can be unclear, wrong, incomplete, or written by someone who isn't a subject matter expert. Sometimes this leads us to make an educated guess at what an end-user requires. We may create a software system in the hope of someone finding it useful and wanting to purchase it from us. Sometimes we may not have direct access to end-users and base all our decisions on second-hand (and sometimes third-hand) information. In situations such as these, we're essentially betting that what we're designing will fulfill the end-user's requirements. Even in a perfect environment, concrete requirements change. When we find out that the behavior does not fulfill the end-user's real requirements, we must change the system. It's when we have to change the behavior of the system that we generally realize that the design is not optimal and should be changed.
Writing software involves creating components that have never been written before. Those components may involve interaction with third-party components. The act of designing and writing the software almost always provides the programmer with essential knowledge of the system under development. Try as we might, we can almost never devise a complete and accurate design before we begin developing a software system. The term Big Design Up Front (BDUF) describes the design technique of devising and documenting a complete design before implementation begins. Unless the design repeats many aspects of an existing design, the act of implementing the design will make knowledge about the system illicit, which will clarify or correct the design. Certain design techniques are based on this truth. Test-Driven Development, for example, is based on realizing the design as the code is written where tests validate the code in implementing requirements of the system.
Regardless of the design technique; when a design needs to change to suit new or changing requirements, aspects of the existing design may need to change to better accommodate future changes.