You are on page 1of 23

Software Construction and

Evolution:
Special Change Called
Refactoring
Learning Outcomes: Refactoring
Apply appropriate refactoring
techniques to resolve design
problems in code
 More perspective on
Software Change
 Opening thoughts on
Refactoring
 Example from Book…
Probably finish on your own

2
Origins of a Change

 What motivation is there for change?

 What are the causes


of a change?

 What are some


categories of change?

3
Change Types/Categories
 Corrective Change – changes to fix errors in design, logic,
coding, documentation
(does not change requirements specifications)

 Adaptive Change – changes for use in a new environment – most


common, your component vendors require moving to a new
version

 Perfective Change – changes to meet new or different customer


needs/requirements – most common, additional
features/capabilities

 Preventive Change (special case of corrective) – change to fix


errors before they occur (this term is not universally used)
 e.g., you know some customers will move to MacOS, fix your app so
it will work there

Q1 4
Or,
New Requirements
Existing
Perfective
Requirements
Corrective
&
Preventive

Existing New Environment


Environment
Adaptive

5
Cost Breakdown by Change Type

Should there be more spent on this?


5%
20%

Corrective
Adaptive
Perfective
50% Preventative
25%

Q2 6
What is Refactoring?
 A disciplined technique for restructuring existing
code, altering internal structure without changing
external behavior

 A series of small behavior preserving


transformations, each doing little, but together
can produce a significant restructuring

 Each refactoring is small, so less likely to go


wrong. The system is kept fully working after
each refactoring, reducing the chance of a
system getting broken

Q3 7
Extremely Simple Example
 Using any number other than zero in functional
code is a road to disaster
 Not clear why that value
 Harder to change the value when rules change

Instead of writing
Feet := Miles * 5280;

Write…
const FEET_PER_MILE = 5280;
Feet := Miles * FEET_PER_MILE;

8
Simple Video Rental Example (1 of 5)
public class Movie {
public static final int CHILDRENS = 2;
public static final int NEW_RELEASE = 1;
public static final int REGULAR = 0;

private String _title;


private int _priceCode;

public Movie(String title, int priceCode) {


_title = title;
_priceCode = priceCode;
}
public int getPriceCode() {
return _priceCode;
}
public void setPriceCode(int arg) {
_priceCode = arg;
}
public String getTitle() {
return _title;
}
} 9
Simple Video Rental Example (2 of 5)

public class Rental {


private Movie _movie;
private int _daysRented;

public Rental(Movie movie, int daysRented) {


_movie = movie;
_daysRented = daysRented;
}
public int getDaysRented() {
return _daysRented;
}
public Movie getMovie() {
return _movie;
}
}

10
Simple Video Rental Example (3 of 5)
public class Customer {
private String _name;
private Vector _rentals = new Vector();

public Customer(String name) {


_name = name;
}
public void addRental(Rental arg) {
_rentals.addElement(arg);
}
public String getName() {
return _name;
}
public String statement() {
double totalAmount = 0;
int frequentRenterPoints = 0;
Enumeration rentals = _rentals.elements();
String result = "Rental Record for " + getName() + "\n";
while (rentals.hasMoreElements()) {
double thisAmount = 0;
Rental each = (Rental) rentals.nextElement();
11
Simple Video Rental Example (4 of 5)

// More of public class Customer :

//determine amounts for each line


switch (each.getMovie().getPriceCode()) {
case Movie.REGULAR:
thisAmount += 2;
if (each.getDaysRented() > 2)
thisAmount += (each.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += each.getDaysRented() * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (each.getDaysRented() > 3)
thisAmount += (each.getDaysRented() - 3) * 1.5;
break;
}

12
Simple Video Rental Example (5 of 5)

// Even more of public class Customer :

// add frequent renter points


frequentRenterPoints++;
// add bonus for a two day new release rental
if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&
each.getDaysRented() > 1)
frequentRenterPoints++;
// show figures for this rental
result += "\t" + each.getMovie().getTitle() + "\t" +
String.valueOf(thisAmount) + "\n”;
totalAmount += thisAmount;
}
// add footer lines
result += "Amount owed is " + String.valueOf(totalAmount) + "\n”;
result += "You earned " + String.valueOf(frequentRenterPoints) +
" frequent renter
points”;
return result;
}
} 13
Some Observations
 Not a very well-designed program
 Not even very object-oriented

 Long statement routine in Customer is heavily


loaded
 Several things could be done in other classes

 Ugly Program, but it works…


 Computer doesn’t care what it looks like
 People who work on it do!

 Poorly developed programs are hard to change


and maintain
Q4 14
Good Software Practice

When you find that you have to add a feature


to a program, …

and the program’s code is not structured in a


convenient way to add the feature, …

1st refactor the program to make it easier to


add the feature, …

then add the feature.

Q5 15
First Step, Before you Start
Refactoring…

 Most software bugs come


from changing software…

 Refactoring is changing
software

 Hence, before you start


making changes, ensure you
have a solid test suite

Q6 16
Redistributing Statement Method (1 of 3)

 Statement method in Customer contains too


much in line stuff

 Use “Extract Method” to pull some of this out into


its own methods

 Problem: You have a code fragment that can be


grouped together to be more relevant and or
cohesive.

 Solution: Turn the fragment into a method whose


name explains the purpose of the method.

Q7 17
Redistributing Statement Method (2 of 3)
private double amountFor(rental each) {
double thisAmount = 0;
switch (each.getMovie().getPriceCode()) {
case Movie.REGULAR:
thisAmount += 2; thisAmount = amountFor(each);
if (each.getDaysRented() > 2)
thisAmount += (each.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += each.getDaysRented() * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (each.getDaysRented() > 3)
thisAmount += (each.getDaysRented() - 3) * 1.5;
break;
}
return thisAmount;
} 18
Redistributing Statement Method (3 of 3)

 Using “Extract Method” refactoring technique to


pull accountFor out into its own method starts to
tidy up Statement

 However, as is often the case when the extraction


is complete, variable names may no longer make
sense

 So, for clarity fix the name of local variables to


clarify the new method…

19
Clarify Names in New Method
private double amountFor(rental aRental) {
double result = 0;
switch (aRental.getMovie().getPriceCode()) {
case Movie.REGULAR:
result += 2;
if (aRental.getDaysRented() > 2)
return += (aRental.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
result += aRental.getDaysRented() * 3;
break;
case Movie.CHILDRENS:
result += 1.5;
if (aRental.getDaysRented() > 3)
return += (aRental.getDaysRented() - 3) * 1.5;
break;
}
return result;
} 20
“Move Method” Technique

 The amountFor method doesn’t use information


from the Customer
 Use the Move Method technique

 Problem: A method is, or will be, using or used by


more features of another class than the class on
which it is defined.

 Solution: Create a new method with a similar body


in the class it uses most. Either turn the old
method into a simple delegation or remove it
altogether.

Q8 21
Move amountFor Method to Rental Class
Class Rental …
double getCharge() { Class Customer…
double result = 0; private double amountFor(rental
switch (getMovie().getPriceCode()) { aRental) {
case Movie.REGULAR: return result;
result += 2; }
if (getDaysRented() > 2)
return += (getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
result += getDaysRented() * 3;
break;
case Movie.CHILDRENS:
result += 1.5;
if (getDaysRented() > 3)
result += (getDaysRented() - 3) * 1.5;
break;
}
return result;
} 22
Exercise: Think/Pair/Share

 How would “Extract Method” be used on


Frequent Renter Points?

 How would “Move Method” be used on


Frequent Renter Points?

23
23

You might also like