Refactoring
Advanced Software Engineering603 492
Dr Nuha El-Khalili
2
What is Refactoring?
• Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
3
Refactoring
• Done by applying series of "refactorings", each of which is tiny change in a source code
• Each transformation does little, but a sequence of transformations can produce a significant restructuring.
• The system is kept fully working after each small refactoring
4
Advantages
• Improved code readability• Reduced complexity• Improve the maintainability
Code smell
• Any symptom in the source code of a program that possibly indicates a deeper problem
• Common code smells– Duplicated code: identical or very similar code exists in
more than one location. – Long method: a method, function, or procedure that
has grown too large. – Large class: a class that has grown too large. – Too many parameters: a long list of parameters in a
procedure or function that reduce readability
Code smell• Common code smells
– Feature envy: a class that uses methods of another class excessively. – Refused bequest: a class that overrides a method of a base class in
such a way that the contract of the base class is not honored by the derived class.
– Lazy class / Freeloader: a class that does too little. – Excessively long identifiers: naming conventions provide
disambiguation– Excessively short identifiers: the name of a variable should reflect its
function unless it's obvious. – Excessive use of literals: these should be coded as named constants,
to improve readability
Refactoring Techniques
• Techniques for breaking code apart – Extract Method, to turn part of a larger method into
a new method– Extract Class moves part of the code from an
existing class into a new class• Techniques that allow for more abstraction– Encapsulate Field – force code to access the field
with getter and setter methods – Generalize Type – create more general types to
allow for more code sharing
Refactoring Techniques
• Organizing Data– Replace Magic Number with Symbolic Constant– Encapsulate Field
• Simplifying Conditional Expression• Moving Features Between Objects– Changing of decisions regarding where to put
reponsibilities• Making Method Calls Simpler– Creating more straightforward interfaces
Extract Methodvoid printOwing(double amount) {
printBanner();
// print detailsstd::cout << “name” << _name << std::endl;std::cout << “amount” << _amount << std::endl;
}/*************************************************************/void printOwing(double amount) {
printBanner();printDetails();
}
void printDetails(double amount) {std::cout << “name” << _name << std::endl;std::cout << “amount” << _amount << std::endl;
}
Example
• Decompose Conditional
if (date.before (SUMMER_START) || date.after(SUMMER_END)) charge = quantity * _winterRate + _winterServiceCharge;else charge = quantity * _summerRate;
if (notSummer(date)) charge = winterCharge(quantity);else charge = summerCharge(quantity);
When should we refactor?
• When we add new functionality• When we fix a bug• When we do a code review
Refactoring and Unit Tests• Relationship between refactoring and Unit tests (?)• Refactoring is strongly dependent on having a good
suite of unit tests• With the unit tests, we can refactor • Then run the automated tests – To verify that the behaviour is indeed preserved.
• Without good unit tests, – developers may shy away from refactoring– Due to the fear that they may break something.
12
Refactoring problems and limitations
• Interfaces: – Refactoring techniques like RenameMethod– change a published interface.
• Databases: – Many applications have code that is tightly coupled with
an underlying database schema.
Tools
• For Visual Studio 2010, download– Code Rush Xpress – Supports VB and C# refactor