You are on page 1of 27

SOFTWARE

MAINTENANCE AND
QUALITY ASSURANCE
Week 5: Refactoring & Code Smells

Salahaddin University
Software and Informatics Engineering
Silva Matti
Fall semester 2021
Notes & Resources

• For Extra information and study:


1. https://www.refactoring.com/catalog/
2. https://sourcemaking.com/refactoring

1/7/2022 2
Refactoring

• Refactoring is code modification (changes made to source


code) while
• Improving internal structure
• Preserving external behavior
• Other words: clean up and re-organization
• NOT to:
• Fix bugs or
• Add functionality
• But to:
• Improve code quality for easier maintenance (as code becomes easy
to understand and easy to update).
• Understanding of code, results MIGHT result in finding bugs while
searching for refactoring opportunities.

1/7/2022 3
Behavior Preservation

Preserving external behavior can be defined as:


before and after the refactoring:
• For the same set of input values,
• The set of output values should be the same

1/7/2022 4
Behavior Preservation : Example
• We are searching for an item in a huge ordered list of
items. The program uses the recursive version of the
binary search of this task.
1. Replace binary search with simpler linear search
• Answer: Is NOT refactoring, performance of the program in worst case
is changing
2. Replacing the recursive version with an iterative
version.
• Answer: Is refactoring, which ever the developer is more comfortable
with.
3. Replacing our implementation of binary search with a
proven available implementation from a library
• Answer: Is refactoring, maintenance effort is reduced
1/7/2022 5
Example 1
• Consolidate duplicate conditional fragments;
• This
if (isSpecialDeal()) {
total = price * 0.95;
send();
} else {
total = price * 0.98;
send();
}
• becomes this
if (isSpecialDeal()) {
total = price * 0.95;
} else {
total = price * 0.98;
}
send();
• Removed the duplicated method calls

1/7/2022 6
Example 2
• Refactor this:

1/7/2022 7
Example 2
• Becomes this

• Replace Nested Conditional with Guard Clauses

1/7/2022 8
Example 3

• Replace magic number with symbolic constant;


• This
double potentialEnergy(double mass, double height){
return mass * 9.81 * height;
}
•becomes this
Static final double GRAVITATIONAL_CONSTANT = 9.81;
double potentialEnergy(double mass, double height)
{
return mass * GRAVITATIONAL_CONSTANT* height;
}
• In this way, refactoring formalizes good programming
practices

1/7/2022 9
Example 4
• This
void CnvrtTemp()
{
// Get the user input
cout<< "Please enter the temperature " << endl;
double d1 =0;
cin>> d1;
// Convert Fahrenheit to Celsius
double d2 = (d1 -32) * 5.0/9.0;
cout<< "Converted temperature is " << d2 << endl;
}

1/7/2022 10
Example 4
• Becomes this
void PrintTemperature()
{
double Fahrenheit= GetUserInput();
cout<< "Converted temperature is " << ConvertFahrenheitToCelsius(Fahrenheit) << endl;
}

double GetUserInput()
{
cout<< "Please enter the temperature " << endl;
double Fahrenheit =0;
cin>> Fahrenheit;
return Fahrenheit;
}

static double ConvertFahrenheitToCelsius(double Fahrenheit)


{
constintOFFSET= 32;
constdouble CONVERSION_FACTOR= 5.0/9;
double Celsius= (Fahrenheit -OFFSET) * CONVERSION_FACTOR;
return Celsius;
}

1/7/2022 11
Refactoring opportunities
• Removing Design defects in code
• Removing Duplicated code (Example 1)
• Removing Dead code
• Using naming conventions in poorly named entities
• Adding Comments
• Removing magical numbers (Example 3)
• Encapsulate field (no public variables)
• Eliminate unused return value
• Removing Switch statements (why?)
• Applying Design Patterns (new concept for you)
• Replace conditional with polymorphism
• Replace error code with exception
• Etc.
1/7/2022 12
Challenges in Refactoring
• BEFORE: Which code to refactor?
i.e. identify the bad smell.
• DURING: We find that we could apply some refactoring to
code.
• Does the order of applying these matter?
• Are there dependencies between a set of refactorings?
• AFTER: Correctness of refactored code

1/7/2022 13
Code Smells*
• Code smell: Symptom that something is potentially wrong
• smells aren't inherently bad on their own - they are often an
indicator of a problem rather than the problem themselves.
• Refactoring fixes smells
• Better design fixes smells

1. a smell is by definition something that's quick to spot


2. smells don't always indicate a problem
3. you have to look deeper to see if there is an underlying
problem there

1/7/2022 14
Code Smells
• Some code smells are:
• God class
• Long method
• Duplicate code
• Magic Number
• Poor self-documentation
• Comment Dissertation
• Dead Code
• Middle Man

1/7/2022 15
God Class
• One class does too many things
• Indicators of a God class
• Tons of attributes (>10)
• No name makes sense
• Name contains a conjunction (e.g. PatientReaderAndWriter)
• Refactoring solutions
• Extract class

1/7/2022 16
Long Method
• Methods that extend beyond the editor window, a method
that has too many responsibilities are
• Too difficult to understand
• takes a long time to process mentally
• make code hard to maintain and debug

• Refactoring solutions:
• Extract method
• Extract class

1/7/2022 17
Duplicate Code / Clones
• Identical or very similar code in 3+ places
• Functionally equivalent, but (possibly) syntactically
different
• Inconsistent fixes
• Redundant efforts (bugs re-appearing in other parts after
refactoring)
• AKA Increased maintenance costs

• Refactoring solutions:
• Extract method
• Extract class

1/7/2022 18
Poor Self Documentation
• Excessive use of single-letter variables
• Lexical scope of more than the current editors window
• Many different single-letter variables
• On comments…
• Only convey what is not obvious
• People don’t maintain comments as well as code
• Make your code obvious first, then use a comment
• “thisIsAReallyLongVariableNameForAnObject”
• Explanatory variables //When a variable is independent, it is not affected at all by any other variables
• Too many: long method
• Too few: one, unreadable line of code

1/7/2022 19
Naming
Uncommunicative Name:
• Does the name of the method describe what that method
does? If you read the method's name to another
developer would they be able to explain what it does? If
not, rename it or rewrite it.
Inconsistent Names:
• Pick a set of standard terminology and stick to it
throughout your methods. For example, if you have
Open(), you should probably have Close().

1/7/2022 20
Comment Dissertation
• Comments Benifits:
• Can have critical information for others
• Provide intended usages
• Document design decisions
• Others

• The dark side:


• Lack of Updating
• Long comments might not be read or updated
• Long comments, if something needs long explanation, maybe
external documentation is the solution

1/7/2022 21
Comment Dissertation cont.
• General advices for comments:
• Does this code explain itself? If so, don’t need comments
• Unexpected line? Call attention to it, but keep it brief
• Is the “why” clear? If not, comment it.
• Will I need this comment 3 months from now?

1/7/2022 22
Dead Code
• Disabling code with a comment
• Quick and easy
• Great for troubleshooting
• BUT.. Leaving it there..
• Easy to forget why you left it there in the first place
• We have version control for this!
• Commit what works now, then delete what you don’t
• You always can go back
• But you’ll be surprised how rarely you go back…

1/7/2022 23
Middle Man
• A class that only acts as delegate to another.
• Developer should think what its real purpose is.
• Sometimes this is the result of a refactoring task, taking
logic out of class gradually, leaving an almost empty shell.
• Example:

1/7/2022 24
Others
• Alternative Classes with • Divergent Change
Different Interfaces • Shotgun Surgery
• Primitive Obsession • Parallel Inheritance
• Data Class Hierarchies
• Data Clumps • Incomplete Library Class
• Refused Bequest • Solution Sprawl
• Inappropriate Intimacy • Speculative Generality
• Indecent Exposure • Oddball Solution
• Feature Envy • Temporary Field
• Lazy Class
• Uncommunicative Name
• Message Chains
• Combinatorial Explosion
• Middle Man
1/7/2022 25
Final Thoughts
• Your code might be easy to understand and be extended
now.
• Still look for code smells and refactoring opportunities to
PREVENT large problems in the future
• USE IDEs that help you refactor your code
• Communicate your changes with your team

1/7/2022 26
•Questions?
•Comments!
•Concerns..

1/7/2022 27

You might also like