What is refactoring?

Code refactoring is a technique used to change the structure and appearance of the code, without changing its external function or the way it behaves. The purpose of refactoring is to make the code more maintainable, readable and more easily built upon.

Why refactor code?

  • Technical Debt

    Technical debt is the amount of sub optimal code in a particular code base. Examples include breaking Single Responsibility, overly complex methods, or plain old “quick fixes." Code laden with technical debt is hard to read and even more difficult to maintain. Many times this code is under test, creating FUD (Fear, Uncertainty and Doubt) in the developers responsible for maintaining it.

    There are many reasons debt creeps into a code base, from junior developers not knowing any better to tight schedules that hinder writing code the “correct” way. After all, releasing is a feature and code not in production does not provide any business value.

    Technical Debt does not always need to be paid back (although one can argue that it should be). The determining factor is the business value of the proposition. If the code is working wonderfully, does not need additional features or bug fixes, a valid option is to leave it alone. However, this is rarely the case. Software seldom stays stagnant, and maintenance is a large part of the corporate developer’s life.

    When saddled with legacy code that has a high cyclomatic complexity or other untenable cruft, refactoring becomes an extremely important tool in the developer's arsenal. Paying back technical debt can be painful, but the return on investment (especially in volatile code bases) is extremely high. It all comes down to saving developer's time and effort (and thus money). Three examples of why refactoring should be used are related to code maintainability, code readability and code extensibility.

  • Code Maintainability

    Although not done intentionally, developers often do not properly document their code as they should. Perfectly written code is perfectly self-documenting. Unfortunately, as developers move away from their projects and someone else takes over them, code maintainability often becomes an issue. Often, serious time is spent just determining what the code does, let alone how best to change it to meet the new feature request or bug fix. Not to mention the risk of introducing side effects when modifying code that is not fully understood. Refactoring makes code more maintainable by drastically reducing the amount of technical debt and preventing legacy code issues.

  • Code Readability

    There is always a better, cleaner, clearer way to develop code, and it usually surfaces after the fact. New techniques, better knowledge, expanded experience, and a deeper understanding of the business domain all help us on the path of continuous improvement.

    In addition to solving today’s problem, code should be self-documenting such that someone else can come in and solve tomorrow’s problem without having to completely start from scratch. Code requires care and feeding, including revision and cleaning up since we seldom (if ever) do it perfectly the first time. Refactoring helps structure the code better and makes it more understandable and easy to read. Refactoring helps to clean up spaghetti code which is too tangled and complex for anyone to understand.

  • Code Extensibility

    The Open-Closed principle states that objects should be open for extension and closed for modification. The need for extension is typically surfaced after the code that needs to be extended is developed (and most likely already in production). Refactoring techniques provide the mechanism to enable extension modifying the underlying behavior. For example refactoring helps the developer adhere to the DRY (don’t repeat yourself) principle so in case changes need to be introduced later on, they will be applied in one place only and time spent looking for duplicate pieces of code will be saved. When should you refactor?

    The simple answer is “constantly”. Refactoring your code should be part of the daily fabric of a developer’s life. It’s part of the Test Driven Development mantra – Red, Green, Refactor. Even if you are not developing test first, continually cleaning the code you are working on provides great benefits to the developer, the team, and the project.

  • The Boy Scout Principle

    The American Boy Scouts have a tenant that they hold dear, and that is to leave everything cleaner than they found it. It does not matter if someone else littered, the Boy Scouts will clean up any area they visit, whether it is hiking, camping, or some other outing. They call it “policing the area."

    As a developer, you should constantly police your code. If you have to pause and think about what a section of code does, clean it up so the next time you are there you will not have to stop what you are doing to analyze its function. If you find methods with high cyclomatic complexity, fix them.

  • Keep it DRY

    Breaking DRY (Don’t Repeat Yourself) can lead to horrible side effects as well as high degree of difficulty maintaining the code. Clipboard Inheritance (copying code from one location to another) adds friction when business logic changes since there are multiple places to update the logic. Often, one or more of the copies fail to get updated, and defects are introduced.

  • Do One Thing but Do It Well

    Any method that has more than one goal creates complexity. As stated in the Single Responsibility Principle, a class or method should have one reason and one reason alone to change. If your method attempts to be a jack-of-all-trades, it will be a master of none. When you find code that is doing too much, refactor it into smaller, well-defined units of work.

Types of refactorings in .NET

Learn more about common refactoring types and see practical refactoring examples with JustCode .NET refactoring tool.