Date post: | 21-Jan-2018 |
Category: |
Internet |
Upload: | godfrey-nolan |
View: | 451 times |
Download: | 0 times |
RefactoringGodfrey Nolan
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
- Martin Fowler
Android Activities
9/25/17 Refactoring 3
Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
"Refactor (verb): to restructure software by applying a series of refactorings without changing its observable behavior".
- Martin Fowler
Goals
9/25/17 Refactoring 5
"Technical debt ..[is]... the implied cost of additional rework caused by choosing an easy solution now instead of using a better approach that would take longer".
- Wikipedia
9/25/17 Refactoring 6
9/25/17 Refactoring 7
Keep it Objective
9/25/17 Refactoring 10
Keep it Objective
9/25/17 Refactoring 11
9/25/17 Refactoring 6
SonarCloud.io
9/25/17 Refactoring 13
SonarCloud.io
9/25/17 Refactoring 14
Metrics Reloaded
9/25/17 Refactoring 15
Metrics Reloaded
9/25/17 Refactoring 16
What’s the Process?
9/25/17 Refactoring 17
Refactor
9/25/17 Refactoring 18
Refactor
9/25/17 Refactoring 19
Rename
9/25/17 Refactoring 20
Move
9/25/17 Refactoring 21
Extract Method
9/25/17 Refactoring 22
Extract Layout
9/25/17 Refactoring 23
Pull Members Up
9/25/17 Refactoring 24
Pull Members Down
9/25/17 Refactoring 25
Convert Anonymous to Inner
9/25/17 Refactoring 26
Replace Temp with Query
9/25/17 Refactoring 27
Lets Begin
9/25/17 Refactoring 28
Lets Begin
9/25/17 Refactoring 29
Lets Begin – Kent Beck Rules
9/25/17 Refactoring 30
• Passes all the tests
• Reveals Intent
• Don’t repeat yourself
• Fewer Parts
Example 1
9/25/17 Refactoring 31
Example 1 – Extract Method
9/25/17 Refactoring 32
Example 1 – Rename
9/25/17 Refactoring 33
Example 1 – Move Method
9/25/17 Refactoring 34
Example 1 – Replace Temp With Query
9/25/17 Refactoring 35
Example 1 – Extract Method
9/25/17 Refactoring 36
Example 1 – Replace Temp With Query
9/25/17 Refactoring 37
Example 1 – Replace Temp With Query
9/25/17 Refactoring 38
Example 1 – Measure Once, Cut Twice
9/25/17 Refactoring 39
9/25/17 Refactoring 40
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();
//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;
}
// 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;
}
9/25/17 Refactoring 41
public String statement() {
String result = "Rental Record for " + getName() + "\n";
for (Rental each : rentals) {
// show figures for this rental
result += "\t" + each.getMovie().getTitle() + "\t" + each.getCharge() + "\n";
}
// add footer lines
result += "Amount owed is " + getTotalCharge() + "\n";
result += "You earned " + getTotalFrequentRenterPoints() + " frequent renter points";
return result;
}
private double getTotalCharge() {
double totalCharge = 0;
for (Rental each : rentals) {
totalCharge += each.getCharge();
}
return totalCharge;
}
private int getTotalFrequentRenterPoints() {
int totalFrequentRenterPoints = 0;
for (Rental each : rentals) {
totalFrequentRenterPoints += each.getFrequentRenterPoints();
}
return totalFrequentRenterPoints;
}
9/25/17 Refactoring 42
double getCharge(int numberOfDaysRented) {
double result = 2;
if (numberOfDaysRented > 2) {
result += (numberOfDaysRented - 2) * 1.5;
}
return result;
}
public void setPriceCode(int priceCode) {
switch (priceCode) {
case REGULAR:
price = new RegularPrice();
break;
case CHILDRENS:
price = new ChildrensPrice();
break;
case NEW_RELEASE:
price = new NewReleasePrice();
break;
default:
throw new IllegalArgumentException("illegal price code");
}
}
Example 2 – Convert app to MVP
9/25/17 Refactoring 43
Example 2 – Extract Delegate
9/25/17 Refactoring 44
Example 2 – Create Interface
9/25/17 Refactoring 45
Example 2 – Fix Activity
9/25/17 Refactoring 46
Example 2 – Fix Presenter
9/25/17 Refactoring 47
Example 3
9/25/17 Refactoring 48
Example 4
9/25/17 Refactoring 49
Lessons Learned
9/25/17 Refactoring 50
• Default Android design pattern is Ball of Mud
• Always create unit tests
• Use the metrics as a guide not as a mandate
• Measure early, measure often
• Think twice before you do a complete rewrite
Resources
• https://dev.to/rly
• http://www.mikamantyla.eu/BadCodeSmellsTaxonomy.html
• https://sonarcloud.io
• https://plugins.jetbrains.com/plugin/93-metricsreloaded
• https://github.com/LiushuiXiaoxia/AndroidStudioRefactor
• https://github.com/mroderick/refactoring-day
• https://www.safaribooksonline.com/library/view/developing-high-quality/9781771375580/
• https://medium.com/google-developers/viewmodels-a-simple-example-ed5ac416317e
9/25/17 Refactoring 51
Resources
9/25/17 Refactoring 52