Whichever programming language you know or you use for your projects, sooner or later you will hear “refactoring” or you already have known the meaning of this word (of course, keep reading). The question in my mind is ready and simple before starting of this article, but explanation and application of “refactoring” is not as simple as you think. How should we determine and approach it.? To explain and understand refactoring, actually we need to know about its prerequisites to know how to get to know correctly. Note that TDD is the basis of “refactoring” and i think each of TDD and “refactoring” have to be thought inseparable because of specific reasons that i will explain some of them as much as i can. Frankly speaking, each of which i wrote are just my personal views and theories and experiences as well.
, First of all, i would like to begin with Martin Fowler’s clear explanation, which leads me to understand the meaning of refactoring.

Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.

We are usually facing some challenging problems on our daily tasks. Problems could arise while writing new modules on our current projects, or while customizing the old components of our API.

Sample scenario; i made an inexcusable mistake in my code and now it turns out as a bug which is ready to bite me (it is so hungry), QA team found this bug in production and sent me back mercilessly. Alright, i know it would be expected. I’m going to resolve it and send it back to test server as soon as possible. This scenario (maybe) will be repeated again and again.

Ideally, these sort of cases should be occurred as few as possible. But the growing code base would constitute some serious issues and risks and must be brought quickly to the attention. It is impossible to say that we can write a code that won’t have any mistakes. Perfectness is violation of the nature of software development. But some methods could be applied to reduce our error rates and bring us closer to be better than before. Nowadays, software technologies and techniques have been evolving rapidly that majority of start-up companies prefer to apply agile techniques to produce a software. Common concerns are both rapidness and effectiveness. So we are thinking about how we can be careful not to fall down while trying to be quick and effective.

What if we want to construct a structure which is suitable to be able to be changed regularly without changing the behavior of system and improved systematically.? What would we need to build such a system that forces us to increase it’s quality naturally. There should be some concerns that we have to consider basically.

As Martin Fowler have said that i have pasted it above, even though the main rule of altering the code is simply not chancing external behavior, there are some activities which we need to perform to be successful. Accepted refactoring techniques are clearly stated that how developers should act to improve their code.

Let’s discuss firstly what the refactoring is and what not ?

What is and What is not ?

Refactoring does not involve adding new features
Refactoring does not involve rewriting or replacing big chunk of code.
It is an evolutionary process which we don’t have to do it within a certain time. Refactoring is a continuous improvement process which the code base can be kept under control by responsible developers
The code base is a living organization that should be carefully observed. Refactoring is a powerful tool to keep your code base alive.
It should be assessed in the development time and should be a separated activity or a task which is assigned to developers (this can vary depending on the activities that some teams determine). There must be two hats to separate that two actions, i mean adding new features or in TDD literature keeping code base green and another hat is for refactoring activities.
Refactoring can be done in planned work.
Its heart is a series of small behavior preserving transformations, each transformation does little, but a sequence of transformations can produce a significant restructuring[1].
Optimization is not refactoring.
Finding bugs and resolving them is not refactoring.
So-called refactoring that takes several days is not a refactoring. This is such a redesigning or something else. Or some kind of awful system design flaw that is quickly to be taken care of by an expert. [2]
Generically, constructing software project is challenging and troublesome work for every stakeholders (from manager to system engineers, developers, testers and others) involved in a software project. Nobody fully foresees design or programming issues before they are completed. Especially, the most frustrating process is to maintain what we have coded so far. However, business side of software projects expects that application is working and meeting its requirements or not. So as you know that explaining the technical difficulties, expenditures and plans for long term values of development of a software would be pain in the ass.

Figure

Refactoring processes helps us to observe and improve the quality of our code base. To keep the code base healthy, we need to consider and spend time on some rules that are accepted by authorities.

Why Do We Need to Refactor ?

To improve the design of the software.
To make it easy to understand and maintain.
To increase reusability.
To help us find bugs.
To be sure it works correctly and meets functional and nonfunctional requirements.
To increase efficiency.
To eliminate duplications.
And so on. As it is clearly seen that all jobs that we are expected to do for refactoring are key activities to increase the quality of the software.

States of Code

Stable code
Codes that marked as “TODO”, which someone is aware of it.
Bad code that nobody is aware of it and nobody knows when that bad code will crash.

Some Best Practices

Always use ” TODO ” to remember what you are going to refactor.
Block / Method / Class that will be refactored should be well documented in order to make a sense afterwards.
Do refactor with small and incremental steps. It allows you to realize the need of redesigning or reengineering somewhere in the code quickly.
If you are working with a team, someone should review what you are coding. Four eyes can see more than two eyes can.
Don’t think that you always must do refactor. Refactor when you need to refactor. When you add a new functionality, changing part can damage the old part of the system. Make some little changes if new changes affect the integration points.
At the end of my post, i want to say that there are of course more subjects which can be written about refactoring. So while i was writting, i have decided to compose it with more than one post. This was an outline discussion article about refactoring. In my next article, it will be more comprehensive and involve some hot tips about test driven development.