![Page 1: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/1.jpg)
Chapter 6: Code Refactoring
Omar Meqdadi
SE 3860 Lecture 6
Department of Computer Science and Software Engineering University of Wisconsin-Platteville
![Page 2: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/2.jpg)
2
Topic Covered
Refactoring Refactoring Categories Refactoring Limitations Refactoring Tools
![Page 3: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/3.jpg)
3
Refactoring
Process of changing a software system in such a way that it Does not alter the external behavior of the code Improves its internal structure
A program restructuring operation to support Design evolution Reuse of object oriented frameworks Preserve the behavioral aspects of the program
![Page 4: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/4.jpg)
Refactoring Specifies
Source to source transformation Remain inside the same language, e.g., C++ to C++ Does not change the programs behavior – according to a
test suite Originally designed for object-oriented languages, but
can also be applied to non-object oriented language features, (i.e., functions)
![Page 5: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/5.jpg)
Refactoring: Why?
Design Preservation Design Evolution Problems
Code changes often lead to a loss of the original design Loss of design is cumulative:
Difficulties in design comprehension Difficulties in preserving design More rapid decay of design
Solution: Refactoring improves the design of existing code
![Page 6: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/6.jpg)
Refactoring: Why?
Comprehension Developer's are most concerned with getting the program
to work, not about future developers Refactoring makes existing code more readable Increases comprehension of existing code, leading higher
levels of code comprehension Often applied in stages
![Page 7: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/7.jpg)
Refactoring: Why?
Debugging Improved program comprehension leads to easier
debugging Increased readability leads to the discovery of possible
errors Understanding gained during debugging can be put back
into the code
![Page 8: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/8.jpg)
Refactoring: Why?
Faster Programming Counterintuitive argument made by Fowler Good design is essential for rapid development Poor design allows for quick progress, but soon slows the
process down Spend time debugging Changes take longer as you understand the system and find
duplicate code
![Page 9: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/9.jpg)
Refactoring: When?
Adding Functionality Comprehension of existing program Preparation for addition
Debugging Comprehension of existing program
Code Review Preparation for suggestions to other programmers Stimulates other ideas Remove bad code smells
![Page 10: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/10.jpg)
Refactoring Catalog
Refactoring entry composed of: Name Summary Motivation Mechanics Examples
![Page 11: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/11.jpg)
Refactoring: Categories
Composing Methods Creating methods out of inlined code
Moving Features Between Objects Changing of decisions regarding where to put
responsibilities Organizing Data
Make working with data easier
![Page 12: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/12.jpg)
Refactoring: Categories
Simplifying Conditional Expressions Making Method Calls Simpler
Creating more straightforward interfaces Dealing with Generalization
Moving methods around within hierarchies Big Refactoring
Refactoring for larger purposes
![Page 13: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/13.jpg)
Composing Methods
Extract Method Inline Method Inline Temp Replace Temp with Query Introduce Explaining Variables Split Temporary Variable Remove Assignments to Parameters Replace Method with Method Object Substitute Algorithm
![Page 14: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/14.jpg)
Remove Assignments to Parameters
Example: Remove Assignments to Parameters
![Page 15: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/15.jpg)
Extract Methods
Create a new method, and name it after the intention of the method (name it by what it does, not by how it does it)
Copy the extracted code from the source method into the new target method
Scan the extracted code for references to any variables that are local in scope to the source method
See whether any temporary variables are used only within this extracted code. If so, declare them in the target method as temporary variables
![Page 16: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/16.jpg)
Extract Methods (cont.)
Look to see whether any local-scope variable are modified by the existing code
Pass into the target method as parameters local scope variables that are read from the extracted code
Compile when you have dealt with all the locally- scoped variables
Replace the extracted code in the source method with a call to the target method
Compile and test
![Page 17: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/17.jpg)
Extract Methods
void compAndPrint() { // compute X // compute Y ... // print X // print Y ... // store X // store Y}
void compute () { // compute X // compute Y print(X, Y); // store X // store Y}
void print(X,Y) { // print X // print Y}
![Page 18: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/18.jpg)
Inline Methods
void compute () { X = next(X); Y = next(Y);}
int next(N) { return N++;}
void compAndPrint() { ... X++; Y++; ...}
![Page 19: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/19.jpg)
Inline Temp
Example:
double basePrice = anOrder.basePrice();return (basePrice > 1000) return (anOrder.basePrice > 1000)
![Page 20: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/20.jpg)
Replace Temp with Query
When: using a temporary variable to hold the result of an expression.
double rectarea = length * width; if (rectarea > 1000) return rectarea * 0.95; else return rectarea * 0.98;
If ( RectArea( ) > 1000 ) return RectArea( ) * 0.95;else return RectArea( ) * 0.98;}
double RectArea( ){ return length * width;}
![Page 21: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/21.jpg)
Split Temp Variable
When: using a temporary variable to hold several expressions.
double temp = 2 * (_height * _widgth);cout << “Perimeter is “ << temp << endl;temp = _height * _width; cout << “Area is “ << temp << endl;
double perimeter = 2 * (_height * _widgth);cout << “Perimeter is “ << perimeter << endl;double area = _height * _width; Cout << “Area is “ << area << endl;
![Page 22: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/22.jpg)
Introduce Explaining Variable
When: You have a complicated expression. Then, Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.
// return = baseprice – quantitydiscount + shippingreturn (quantity*price)-((quantity-50)*discount) +price * 0.05
double baseprice = quantity * price;double quantitydiscount = (quantity-50)*discount;double shipping =price * 0.05;return baseprice – quantitydiscount + shipping;
![Page 23: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/23.jpg)
Moving Object Features
Move Method Move Field Extract Class Inline Class Hide Delegate Remove Middle Man Introduce Foreign Method Introduce Local Extension
![Page 24: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/24.jpg)
Move Method
When: if a method is used by another class more than the class on which its defined, move it to the other class
class Student { bool IsEnroll(Course course) { return (course.getStudents().contains(this)); } }
class Course { Student students[size]; Student * getStudents() { return students; } }
class Student { }
public class Course { Student students[size]; bool isEnroll(Student student) { return students.contains(student); } }
![Page 25: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/25.jpg)
Extract Class
class Student{ private: string name; string street; string city; string state; }
class Student{ private: string name; Address address; }
class Address{ private: string street; string city; string state; }
![Page 26: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/26.jpg)
Inline Class
When: a class that isn’t doing too much and shouldn’t be around any more. Then, move all its features to another class. So inline class is the reverse of Extract Class
![Page 27: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/27.jpg)
Hide Delegate
When: a client calls a delegate class of an object Refactoring: create methods on the server to hide the delegate
Client must know about Person and Department
Person must know about department
Client only calls Person
Person calls department
![Page 28: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/28.jpg)
Hide Delegate Class Person {
Department _department;
public Department getDepartment()
{ return _department;}
public void setDepartment (Department arg)
{ _department = arg;}
} // end person
Class Department {
private String _chargeCode;
private Person _manager;
public Department (Person manager)
{ _manager = manager; }
public Person getManager()
{ return _manager; }// end Dept
Client Class:
joe.getDepartment().getManager();
Person Class:
public Person getManager () {
return _department.getManager();
} // end getManager
Client Class:
manager = joe.getManager();
![Page 29: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/29.jpg)
Remove Middle Man
When: after several “Hide delegate”, the server becomes just a middle man for all the delegate methods.
Refactoring: Change the client to call the delegate directly
Client only calls Person
Person calls department
Client must know about Person and Department
Person must know about department
![Page 30: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/30.jpg)
Introduce Foreign Method
When: a server class needs an additional methods, but you can’t modify it
Refactoring: Create the method in the client class Set one of the argument of the method to the instance of
the server class StrDate newStart = new Date
(previousEnd.getYear(),
previousEnd.getMonth(),
previousEnd.getDate()+ 1);
Date newStart = nextDat(previousEnd);
private static Date nextDay (Date arg)
{
return new Date (arg.getYear(),arg.getMonth(),
arg.getDate() + 1);
} // end nextDay
![Page 31: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/31.jpg)
Introduce Local Extension
When: a class needs several additional methods, but you can’t modify it ( such as server class)
Refactoring: Create a new class that contains these additional methods Make the new class a subclass of the original one
(inheritance) or use wrapper approach (delegation)
![Page 32: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/32.jpg)
Organizing Data
Self Encapsulate Field Replace Data Value with Object Change Value to Reference Change Reference to Value Replace Array with Object Duplicate Observed Data Change Unidirectional Association to Bidirectional Change Bidirectional Association to Unidirectional
![Page 33: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/33.jpg)
Organizing Data (cont.)
Replace Magic Number with Symbolic Constant Encapsulate Field Encapsulate Collection Replace Record with Data Class Replace Type Code with Class Replace Type Code with Subclasses Replace Type Code with State/Strategy Replace Subclass with Fields
![Page 34: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/34.jpg)
Change Reference to Value
void swap ( int * x , int * y){ int temp = *x; *x = *y; *y = temp;}void main (){ int a = 5; int b = 7; swap (&a , &b);}
void swap ( int &x , int &y){ int temp = x; x = y; y = temp;}void main (){ int a = 5; int b = 7; swap (a , b);}
![Page 35: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/35.jpg)
Replace Array with Object
String[] row = new String[3];row[0] = “Platteville”;row[1] = “15”;
Performance row = new Performance();row.setName(“Platteville”);row.setWins(“15”);
![Page 36: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/36.jpg)
Encapsulate Field
![Page 37: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/37.jpg)
Replace Magic Number with Constant
Example:
double Energy (double m, double h) {
return m * 9.81 * h;
}
static Final double GRAVITATIONAL_CONSTANT * 9.81;
double Energy (double m, double h) {
return m * GRAVITATIONAL_CONSTANT * h;
}
![Page 38: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/38.jpg)
Simplifying Conditional
Decompose Conditional Consolidate Conditional Expression Consolidate Duplicate Conditional Fragments Remove Control Flag Replace Nested Conditional with Guard Clauses Replace Conditional with Polymorphism Introduce Null Object Introduce Assertion
![Page 39: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/39.jpg)
Decompose Conditional
Example: Decompose Conditional
![Page 40: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/40.jpg)
Consolidate Conditional
double disabilityAmount() { if (_seniority < 2) return 0; if (_monthsDisabled > 12) return 0; if (_isPartTime) return 0; // do smoething else}
double disabilityAmount() {{ if (isNotEligableForDisability()) return 0; // do something else}
bool isNotEligableForDisability(){ if (_seniority < 2 || _monthsDisabled > 12 || _isPartTime() ) return false; else return true;}
![Page 41: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/41.jpg)
Consolidate Duplicate Conditional Fragments
if (isSpecial()) { total = price * 0.95; send(); }else{ total = price * 0.98; send();}
if (isSpecial()) { total = price * 0.95;}else{ total = price * 0.98;}
Send();
![Page 42: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/42.jpg)
Introduce Null Objects
When: for null or default behavior, use inheritance
class Animal { Voice MakeSound() { return voice; } }
Animal obj = new Animal;if (obj == null) voice = Voice.basic();else voice = obj.MakeSound();
class Animal{ Voice MakeSound() { return voice; }}
class NullAnimal : public Animal{ Voice MakeSound() { return Voice.basic(); }}
![Page 43: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/43.jpg)
Replace Nested Conditional with Guard
When: A method has unclear conditional behavior. Then , use Guard Clauses for all the special cases
double getAmount() { double result; if (isDead ()) result = deadAmount(); else { if (isSeparated( ) ) result = separatedAmount(); else { if (isRetired ( ) ) result = retiredAmount(); else result = normalPayAmount(); } } return result;}
double getAmount() { if (isDead ( ) ) return deadAmount(); if (isSeparated ( ) ) return separatedAmount(); if (isRetired ( ) ) return retiredAmount(); return normalPayAmount();}
![Page 44: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/44.jpg)
Replace Conditional with Polymorphism
class Bird {……double getSpeed() { switch (_type) { case EUROPEAN: return getBaseX(); case AFRICAN: return getBaseX() – _number; }}…..
![Page 45: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/45.jpg)
Introduce Assertion
When: the code assumes something. Then, make the assumption explicit with an assertion.
double getExpenseLimit() {
// should have either expense limit or // a primary // project
return (_expenseLimit != NULL_EXPENSE) ?
_expenseLimit:
_primaryProject.getMemberExpenseLimit();
}
double getExpenseLimit() {
Assert.isTrue (_expenseLimit != NULL_EXPENSE || _primaryProject != null);
return (_expenseLimit != NULL_EXPENSE) ?
_expenseLimit:
_primaryProject.getMemberExpenseLimit();
}
![Page 46: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/46.jpg)
Remove Control Flag
When: remove a control flag and use break or return void checkSecurity( ) {
bool found = false;
for (int i = 0; i <length; i++) {
if (! found) {
if(people[i].equals("Don")){
sendAlert();
found = true; }
if(people[i].equals ("John")){
sendAlert();
found = true; }
}
}
}
void checkSecurity( ) {
for (int i = 0; i <length; i++) {
if(people[i].equals("Don")){
sendAlert();
break; }
if(people[i].equals ("John")){
sendAlert();
break; }
}
}
![Page 47: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/47.jpg)
Simplifying Method Calls
Rename Method Add Parameter Remove Parameter Separate Query from Modifier Parameterize Method Replace Parameter with Explicit Methods Preserve Whole Object Replace Parameter with Method
![Page 48: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/48.jpg)
Simplifying Method Calls(cont.)
Introduce Parameter Object Remove Setting Method Hide Method Replace Constructor with Factory Method Encapsulate Downcast Replace Error Code with Exception Replace Exception with Test
![Page 49: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/49.jpg)
Remove Setting Method
When: A field should be set at creation time and never altered. Then, remove any setting method for that field.
class Account {
private String _id;
Account (String id)
{ setId(id); }
void setId (String arg)
{ _id = arg; }
}
class Account {
private String _id;
Account (String id)
{ _id = arg; }
}
![Page 50: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/50.jpg)
Hide Method
When: A method is not used by any other class
Refactoring: Make the method private
![Page 51: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/51.jpg)
Parameterize Method
When: Several methods do similar things but with different values contained in the method body. Then, Create one method that uses a parameter for the different values.
class Employee {
void tenPercentRaise () {
salary *= 1.1; }
void fivePercentRaise () {
salary *= 1.05;}
}
class Employee {
void Raise (double factor) {
salary *= (1+ factor); }
}
![Page 52: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/52.jpg)
Replace Parameter with Explicit Method
When: a method that runs different cases depending on the values of a parameter. Then, create a separate method for each value of the parameter
void setValue (string name, int value) { if (name.equals("height")) height = value; if (name.equals("width")) width = value; }
void setHeight(int value) { height = value;}
void setWidth (int value) { width = value;}
![Page 53: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/53.jpg)
Introduce Parameter Object
When: a group of parameters that naturally go together. Then , replace them with an object
![Page 54: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/54.jpg)
Preserve Whole Object
When: You are getting several values from an object and passing these values as parameters in a method call. Then, send the whole object instead.
int low = daysTempRange.getLow();
int high = daysTempRange.getHigh();
withinPlan = plan.withinRange(low, high);
withinPlan = plan.withinRange(daysTempRange);
![Page 55: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/55.jpg)
Replace Error Code with Exception
When: A method returns something to indicate an error is better performed with an Exception
bool withdraw(int amount) { if (amount > balance) return false; else { balance -= amount; return true; }}
void withdraw(int amount) throws BalanceException { if (amount > balance) { throw new BalanceException(); } balance -= amount;}
![Page 56: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/56.jpg)
Replace Exception with Test
When: if you are catching an exception that could be handled by an if-statement, use that instead
int getValuebyIndex (int index) { try { return values[index]; } catch (ArrayIndexOutOfBoundsException e) { return 0; }}
int getValuebyIndex (int index) { if (index >= values.length) return 0; return values[index]; }
![Page 57: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/57.jpg)
Replace Constructor with Factory Method
Factory Class: A utility class that creates an instance of a class from a
family of derived classes Useful in a situation that requires the creation of many
different types of objects, all derived from a common base type
![Page 58: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/58.jpg)
Replace Constructor with Factory Method
Class Computer
{
………
};
class Laptop: public Computer
{
………
};
class Desktop: public Computer
{
......
};
class ComputerFactory {
public:
static Computer *NewComputer(const std::string &description)
{
if(description == "laptop")
return new Laptop;
if(description == "desktop")
return new Desktop;
return NULL;
}
};
Client Side:
Computer * lapobj = ComputerFactory::NewComputer(“laptop”);
Computer * deskobj = ComputerFactory::NewComputer(“desktop”);
![Page 59: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/59.jpg)
Dealing with Generalization
Pull Up Field Pull Up Method Pull Up Constructor Body Push Down Method Push Down Field Extract Subclass Extract Superclass Extract Interface
![Page 60: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/60.jpg)
Dealing with Generalization
Collapse Hierarchy Form Template Method Replace Inheritance with Delegation Replace Delegation with Inheritance
![Page 61: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/61.jpg)
Method/Field Movement
Pull Up Method/Field When: Two subclasses have the same method/field Refactoring: Move the method/field to the superclass
Push Down Method/Field When: A method/field is only used in subclass Refactoring: move the method/field to the subclass
![Page 62: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/62.jpg)
Method/Field Movement
Example: Push Down Method
![Page 63: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/63.jpg)
Pull Up Constructor Body
When: constructors on subclasses with mostly identical bodies.
Refactoring: Create a superclass constructor; call this from the subclass
methods
![Page 64: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/64.jpg)
Pull Up Constructor Body
class Employee{
private:
string name;
string id;
}
class Manager : public Employee{
private:
int grade;
public:
Manager (string n, string i, int g) {
name = n;
id = i;
grade = g;
}
}
class Employee{
private:
string name;
string id;
public:
Employee(string n , string I ){
name = n;
id = I;
}
}
class Manager : public Employee{
private:
int grade;
public:
Manager (string n, string i, int g) {
Employee (n, i);
grade = g;
}
}
![Page 65: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/65.jpg)
Extract Subclass
When: A class has features that are used only in some instances. Then, create a subclass for that subset of features
![Page 66: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/66.jpg)
Extract Subclass
class JobItem ...
public JobItem (int unitPrice, int quantity,
boolean isLabor, Employee employee) {
_unitPrice = unitPrice;
_quantity = quantity;
_isLabor = isLabor;
_employee = employee; }
public int getTotalPrice() {
return getUnitPrice() * _quantity;
}
public int getUnitPrice(){
return (_isLabor) ? _employee.getRate() : _unitPrice;
}
public int getQuantity(){
return _quantity;
}
public Employee getEmployee() {
return _employee;
}
private int _unitPrice;
private int _quantity;
private Employee _employee;
private boolean _isLabor;
class Employee...
public Employee (int rate) {
_rate = rate;
}
public int getRate() {
return _rate;
}
private int _rate;
class JobItem...
protected JobItem (int unitPrice, int quantity,
boolean isLabor) {
_unitPrice = unitPrice;
_quantity = quantity;
protected boolean isLabor() {
return false;
}
public int getUnitPrice(){
return _unitPrice;
}
class LaborItem extends JobItem
public LaborItem (int quantity, Employee employee) {
super (0, quantity, true);
_employee = employee;
}
protected boolean isLabor() {
return true;
}
public int getUnitPrice(){
return _employee.getRate();
}
![Page 67: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/67.jpg)
Extract Superclass
When: several classes with similar features
class Employee { private: string name; string jobTitle; public: string GetName();}
class Student { private: string name; Course course;public: string GetName(); }
class Person { private: string name; public: string GetName();}
class Employee : public Person { private: string jobTitle; }
class Student : public Person { private: Course course; }
![Page 68: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/68.jpg)
Extract Interface
When: several classes have part of their interface in common
Interface: is an empty shell, there are only the signatures (name / params / return type) of the methods. The methods do not contain anything. The interface can't do anything. It's just a pattern.
![Page 69: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/69.jpg)
Extract Interface
double charge(Employee emp, int days) { int base = emp.getRate() * days; if (emp.hasSpecialSkill()) return base * 1.05; else return base;}
interface Billable { public int getRate(); public boolean hasSpecialSkill();}
class Employee implements Billable ...
double charge(Billable emp, int days) { int base = emp.getRate() * days; if (emp.hasSpecialSkill()) return base * 1.05; else return base;}
![Page 70: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/70.jpg)
Collapse Hierarchy
When: A superclass and subclass are not very different
Refactoring Solution: Merge them together
![Page 71: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/71.jpg)
Replace Inheritance with Delegation
When: A subclass uses only part of a superclasses interface or
does not want to inherit data. Refactoring Solution:
Create a field for the superclass, change methods to delegate to the superclass, and remove the subclassing
![Page 72: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/72.jpg)
Replace Inheritance with Delegation
Example:
class MyStack extends Vector {
public void push(Object element) {
insertElementAt(element,0);
}
public Object pop() {
Object result = firstElement();
removeElementAt(0);
return result;
}
class MyStack {
private Vector _vector = new Vector();
public boolean isEmpty() {
return _vector.isEmpty();
}
public void push(Object element) {
_vector.insertElementAt(element,0);
}
public Object pop() {
Object result = _vector.firstElement();
_vector.removeElementAt(0);
return result;
}}
![Page 73: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/73.jpg)
Big Refactoring
Tease Apart Inheritance Split an inheritance hierarchy that is doing two jobs at once
Convert Procedural Design to Objects Separate Domain from Presentation
GUI classes that contain domain logic Extract Hierarchy
Create a hierarchy of classes from a single class where the single class contains many conditional statements
![Page 74: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/74.jpg)
Convert Procedural Design
Take each record type and turn it into a dumb data object with accessors
Take all procedural code and put it into a single class Take each long method and apply Extract Method and the
related factorings to break it down. As you break down the procedures use Move Method to move each one to the appropriate dumb data class
Continue until all behavior is removed from the original class
![Page 75: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/75.jpg)
Convert Procedural Design
Example:
![Page 76: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/76.jpg)
Refactoring: Limitations
Tentative list due to lack of experience Database
Database schema must be isolated, or schema evolution must be allowed
Changing Published Interfaces Interfaces where you do not control all of the source code that
uses the interface Must support both old and new interfaces Don't publish interfaces unless you have to
![Page 77: Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville](https://reader037.vdocuments.site/reader037/viewer/2022110210/56649eb65503460f94bbf041/html5/thumbnails/77.jpg)
Refactoring: Tools
Smalltalk Refactoring Browser Development environment written in Smalltalk Allows for Smalltalk source code to transform Smalltalk source
code Comments as a first-class part of the language
XRefactory Allows standard refactorings for C++