Refactoring - WordPress.com

advertisement
Software Engineering
Refactoring
CIT2C06 Software Engineering
AY 2006/2007 Oct Semester
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Objectives
 Describe
 List
the purpose of code refactoring.
code smells.
 Apply
code refactoring.
2
TEMASEK INFORMATION TECHNOLOGY SCHOOL
What is Code Refactoring
 The
process of changing a software system in such a
way that it:
 improves the internal code structure
 does not alter external behavior
of code
public class Student {
public String name;
public static void main(String[] args) {
Student s1 = new Student();
s1.name = “Tan Ah Beng”;
Student s2 = new Student();
s2.name = “Lim Ah Seng”;
}
}
Any problems with this code?
3
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Code Refactoring in Action
 Use
getter and setter methods
 Step 1: Create getter and setter methods
public class Student {
public String name;
public String getName() { return name; }
public void setName(String newName) {
name = newName;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.name = “Tan Ah Beng”;
Student s2 = new Student();
s2.name = “Lim Ah Seng”;
}
}
4
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Code Refactoring in Action
 Step
2: Find all clients; replace references with calls.
Do this one at a time
public class Student {
public String name;
public String getName() { return name; }
public String setName(String newName) {
name = newName;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.setName(“Tan Ah Beng”);
Student s2 = new Student();
s2.name = “Lim Ah Seng”;
}
}
5
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Code Refactoring in Action
 Step
3: Compile and test
 Back to step 2: Replace other references
public class Student {
public String name;
public String getName() { return name; }
public String setName(String newName) {
name = newName;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.setName(“Tan Ah Beng”);
Student s2 = new Student();
s2.setName(“Lim Ah Seng”);
}
}
6
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Code Refactoring in Action
 Back
to step 3: Compile and test
 Step 4: Once all clients are changed, make the field
private
 Step 5: Compile and test one last time
public class Student {
private String name;
public String getName() { return name; }
public String setName(String newName) {
name = newName;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.setName(“Tan Ah Beng”);
Student s2 = new Student();
s2.setName(“Lim Ah Seng”);
}
}
7
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Refactoring
 Why
refactor?
 Improves the design of software
 Makes software easier to understand
 Helps you find bugs
 Helps you program faster
 When
do we refactor?
 When you add function
 When you need to fix a bug
 When you do a code review
8
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Detecting Code Smells
 Code
smells are warning signs about problems within
the code
 Common smells
 Duplicated code
 Long methods
 Long parameter list
 Large classes (in terms of instance variables, methods
and lines)
 Data clumps (groups of data items appearing together in
lots of places)
 Comments (is it really a bad smell?)
9
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Refactoring Cycle
1.
2.
Start with a working program
While smells remain
a. Choose the worst smell
b. Select a refactoring that will address the smell
c. Apply the refactoring

Remember: the condition for refactoring safely is to
have tests to cover those code we want to refactor
10
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Code Refactoring
 Parameterize
 Pass
method
Whole Object
 Replace
Magic Number with Named Constants
11
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Parameterize Method
 Several
methods do similar things but each uses
different values
 Replace them with one method that uses a parameter
for the different values
Toy
getTenPercentDiscountedPrice():double
getFivePercentDiscountedPrice():double
Toy
getDiscountedPrice(percent):double
12
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Parameterize Method Example
public class Wizard {
private int willPower;
public int castFireSpell(int damage) {
return damage + (willPower * 1.1);
}
public int castColdSpell(int damage) {
return damage + (willPower * 2.1);
}
public static void main(String[] args) {
……………………………
damage = wizard.castFireSpell(damage);
damage = wizard.castColdSpell(damage);
……………………………
}
}
13
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Parameterize Method in Action
public class Wizard {
private int willPower;
public int castFireSpell(int damage) {
return damage + (willPower * 1.1);
}
public int castColdSpell(int damage) {
return damage + (willPower * 2.1);
}
public int castSpell(int damage, int factor) {
return damage + (willPower * factor);
}
public static void main(String[] args) {
……………………………
damage = wizard.castFireSpell(damage);
damage = wizard.castColdSpell(damage);
……………………………
}
}
14
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Parameterize Method in Action
public class Wizard {
private int willPower;
public int castFireSpell(int damage) {
return damage + (willPower * 1.1);
}
public int castColdSpell(int damage) {
return damage + (willPower * 2.1);
}
public int castSpell(int damage, int factor) {
return damage + (willPower * factor);
}
public static void main(String[] args) {
……………………………
damage = wizard.castSpell(damage,1.1);
damage = wizard.castColdSpell(damage);
……………………………
}
}
15
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Parameterize Method in Action
public class Wizard {
private int willPower;
public int castFireSpell(int damage) {
return damage + (willPower * 1.1);
}
public int castColdSpell(int damage) {
return damage + (willPower * 2.1);
}
public int castSpell(int damage, int factor) {
return damage + (willPower * factor);
}
public static void main(String[] args) {
……………………………
damage = wizard.castSpell(damage,1.1);
damage = wizard.castSpell(damage,2.1);
……………………………
}
}
16
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Pass Whole Object
 You
get several values from an object and pass these
values as parameters in a method call
 Send the whole object instead
int low = tempRange.getLow();
int high = tempRange.getHigh();
int ave = monitor.computeAverage(low, high);
int ave = monitor.computeAverage(tempRange);
17
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Pass Whole Object Example
class Game {
void throwGrenade(Person rambo, Grenade g) {
int xPos = rambo.getX();
int yPos = rambo.getY();
if (g.isWithinRange(xPos, yPos))
rambo.addDamage(10);
}
}
class Grenade {
boolean isWithinRange(int xPos, int yPos) {
if ((xPos >= gx) && (xPos <= gx + 25) &&
(yPos >= yx) && (yPos <= yx + 25))
return true;
else
return false;
}
}
18
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Pass Whole Object in Action
class Game {
void throwGrenade(Person rambo, Grenade g) {
int xPos = rambo.getX();
int yPos = rambo.getY();
if (g.isWithinRange(rambo, xPos, yPos))
rambo.addDamage(10);
}
}
class Grenade {
boolean isWithinRange(Person r, int xPos, int yPos) {
if ((xPos >= gx) && (xPos <= gx + 25) &&
(yPos >= yx) && (yPos <= yx + 25))
return true;
else
return false;
}
}
19
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Pass Whole Object in Action
class Game {
void throwGrenade(Person rambo, Grenade g) {
int xPos = rambo.getX();
int yPos = rambo.getY();
if (g.isWithinRange(rambo, xPos, yPos))
rambo.addDamage(10);
}
}
class Grenade {
boolean isWithinRange(Person r, int xPos, int yPos) {
if ((r.getX() >= gx) && (r.getX() <= gx + 25) &&
(r.getY() >= yx) && (r.getY() <= yx + 25))
return true;
else
return false;
}
}
20
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Pass Whole Object In Action
class Game {
void throwGrenade(Person rambo, Grenade g) {
int xPos = rambo.getX();
int yPos = rambo.getY();
if (g.isWithinRange(rambo, xPos, yPos))
rambo.addDamage(10);
}
}
class Grenade {
boolean isWithinRange(Person r, int xPos, int yPos) {
if ((r.getX() >= gx) && (r.getX() <= gx + 25) &&
(r.getY() >= yx) && (r.getY() <= yx + 25))
return true;
else
return false;
}
}
21
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Replace Magic Number with Named Constant
 In
your code, you use literals directly
 Instead of using the literals directly, create a constant
giving it an appropriate name, and use the constant
instead
double parcelAmount (double wt) {
return 0.50 * wt;
}
private final static double AIRMAIL_RATE = 0.50;
double parcelAmount (double wt) {
return AIRMAIL_RATE * wt;
}
22
TEMASEK INFORMATION TECHNOLOGY SCHOOL
Recap
 What
is refactoring and why is it important?
 Describe 3 code smells.
 Give examples on the application of the following
refactorings:
 Parameterize Method
 Pass Whole Object
 Replace Magic Number with Named Constant
23
Download