0% found this document useful (0 votes)
79 views

Refactoring

Refactoring is the process of restructuring code without changing its functionality to improve code quality. The document discusses reasons for refactoring like duplicated code, long routines, and poor class cohesion. It also provides examples of specific refactorings at the data, statement, routine, class, and system levels.

Uploaded by

Muhammad Uzair
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
79 views

Refactoring

Refactoring is the process of restructuring code without changing its functionality to improve code quality. The document discusses reasons for refactoring like duplicated code, long routines, and poor class cohesion. It also provides examples of specific refactorings at the data, statement, routine, class, and system levels.

Uploaded by

Muhammad Uzair
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 6

Refactoring:

Refactoring is the process of restructuring code, while not changing its original
functionality. The goal of refactoring is to improve internal code by making
many small changes without altering the code's external behavior.

Reasons to Refactor:
1) Code is duplicated:
If your code is duplicated, whenever you have to make changes in one place,
you have to make parallel changes in another place.

2) A routine is too long:


In object-oriented programming, routines longer than a screen are rarely
needed, and usually represent the attempt to force-fit a structured
programming approach into an object-oriented approach.

3) A loop is too long or too deeply nested:


Refactoring a loop that is too long or deeply nested helps to reduce the
complexity and increase understandability.

4) A class has poor cohesion:


If a class has taken unrelated responsibilities that class should be broke up into
multiple class each of which has responsibility for a cohesive set of
responsibilities.

5) A parameter list has too many parameters:


A long parameter list is a warning that the abstraction of the routine interface
has not been well thought out.

6) Changes require parallel modifications to multiple


classes:
When you find yourself routinely making changes to the same set of classes,
that suggests the code in those classes could be rearranged so that changes
affect only one class.
7) A routine uses more features of another class than of its
own class:
This suggests that the routine should be moved into the other class and then
invoked by its old class.

8) A class doesn’t do very much:


If a class doesn’t seem to be carrying its weight, assign all of that class’s
responsibilities to other classes and eliminate the class altogether.

9) A routine has a poor name:


If a routine has a poor name, change the name of the routine where it’s
defined, change the name in all places it’s called, and then recompile.

10) Data members are public:


Public data members are always a bad idea. They blur the line between
interface and implementation. They inherently violate encapsulation and limit
future flexibility.

11) Comments are used to explain difficult code:


Comments have an important role to play, but they should not be used to
explain bad code. “Don’t document bad code—rewrite it”.

12) A program contains future requirements:


Experts agree that the best way to prepare for future requirements is not to
write speculative code; it’s to make the currently required code as clear and
straightforward as possible so that future programmers will know what it does
and does not do, and can make their changes accordingly.

Specific Refactorings:
Data Level Refactorings:
Replace a magic number with a named constant
If you’re using a numeric or string literal like 3.14, replace that literal with a
named constant like PI.
Rename a variable with a clearer or more informative name
If a variable’s name isn’t clear, change it to a better name.
Move an expression inline
Replace an intermediate variable that was assigned the result of an expression
with the expression itself.
Replace an expression with a routine
Replace an expression with a routine (usually so that the expression isn’t
duplicated in the code).
Introduce an intermediate variable
Assign an expression to an intermediate variable whose name summarizes the
purpose of the expression.
Convert a multi-use variable to multiple single-use variables
If a variable is used for more than one purpose, create separate variables for
each usage.

Statement Level Refactorings:


Decompose a Boolean expression
Simplify a Boolean expression by introducing well named intermediate
variables that help document the meaning of the expression.
Consolidate fragments that are duplicated within different parts of a
conditional
If you have the same lines of code repeated at the end of an else block that
you have at the end of the if block, move those lines of code so that they occur
after the entire if then-else block.
Use break or return instead of a loop control variable
If you have a variable within a loop like Done that’s used to control the loop,
use break or return to exit the loop instead.
Return as soon as you know the answer
Code is often easiest to read and least error prone if you exit a routine as soon
as you know the return value.
Create and use null objects
Sometimes a null object will have generic behavior or data associated with it,
such as referring to a resident whose name is not known as “occupant.”

Routine Level Refactorings:


Move a routine's code inline

Take code from a routine whose body is simple and self-explanatory, and move
that routine's code inline where it is used.

Convert a long routine to a class

If a routine is too long, sometimes turning it into a class and then further
factoring the former routine into multiple routines will improve readability.

Substitute a simple algorithm for a complex algorithm

Replace a complicated algorithm with a simpler algorithm.

Add a parameter

If a routine needs more information from its caller, add a parameter so that
that information can be provided.

Remove a parameter
If a routine no longer uses a parameter, remove it.

Class level Refactorings:


Combine similar code into a superclass

If two subclasses have similar code, combine that code and move it into the
superclass.

Convert one class to two

If a class has two or more distinct areas of responsibility, break the class into
multiple classes, each of which has a clearly defined responsibility.
Eliminate a class

If a class isn’t doing very much, move its code into other classes that are more
cohesive and eliminate the class.

Remove a middle man

If Class A calls B, and Class B calls Class C, sometimes it works better to have
Class A call Class C directly.

Encapsulate an exposed member variable

If member data is public, change the member data to private and expose the
member data’s value through a routine instead.

System Level Refactorings


Change unidirectional class association to bidirectional class association

If you have two classes that need to use each other’s features, but only one
class can know about the other class, then change the classes so that they both
know about each other.

Change bidirectional class association to unidirectional class association

If you have two classes that know about each other’s features, but only one
class that really needs to know about the other, change the classes so that one
knows about the other, but not vice versa.

Replace error codes with exceptions or vice versa

Depending on your error-handling strategy, make sure the code is using the
standard approach.

Refactoring Safely:
 Save the code you start with — Before you begin refactoring, make sure
you can get back to the code you started with.
 Keep refactorings small — Keep the refactorings small so that you fully
understand all the impacts of the changes you make.
 Do refactorings one at a time — Do the refactorings one at a time,
recompile, and retest, then do the next refactoring.
 Make a list of steps you intend to take — Making a list helps you keep
each change in context.
 Make frequent checkpoints — Save checkpoints at various steps in a
refactoring session so that you can get back to a working program if you
code yourself into a dead end.
 Use your compiler warnings — Setting your compiler to the pickiest
warning level possible will help catch many errors almost as soon as you
type them.
 Add test cases — In addition to retesting with your old tests, add new
unit tests to exercise the new code.

Refactoring Strategies:
Refactor when you add a routine:

When you add a routine, check whether related routines are well organized. If
not, refactor them.

Refactor when you add a class:

Adding a class often brings issues with existing code so it’s better to refactor
when you add a class.

Refactor when you fix a defect:

Use the understanding you gain from fixing a bug to improve other code that
might be prone to similar defects.

In a maintenance environment, improve the parts you touch:

Code that is never modified doesn’t need to be refactored. But when you do
touch a section of code, be sure you leave it better than you found it.

You might also like