CS代考计算机代写 Java SE 333/433 Software Testing & Quality Assurance

SE 333/433 Software Testing & Quality Assurance
Refactoring
1

Last Week
2

Another System Model (Data-Bases)
Program (in Java)
Model transformation
Refactoring
System Model (in UML)
Reverse engineering
Another Program (Java)
Model space
Source code space
3
Forward engineering

• Design to code • Refactoring
4

Class and Attribute
float
float
5

float float
float float
Operations
6

Visibility
7

Class scope
8

Unidirectional Association
11
Advertiser Account
public class Advertiser { private Account account;
} }
public Advertiser() {
account = new Account();
}
public Account getAccount() {
return account;
9

Association names & role defaults
10

public class Advertiser { /* account is initialized
public class Account {
/* owner is initialized
} }
private Account account; public Advertiser() {
* never modified. */
private Advertiser owner;
public Account(owner:Advertiser) {
Bi‐directional Association
Advertiser
Account
* in the constructor and never
* modified. */
* in the constructor and
account = new Account(this);
this.owner = owner; }
}
public Account getAccount() {
public Advertiser getOwner() { return owner;
return account;
} }
11
11

Multiplicity
12

Aggregation and Composition
13

Generalization
14

Realization
15

Abstraction
16

Association classes
17

Associations, Visibility & Scope
18

?
public int getX() { return _x;
}
Example
public class Point { private int _x; private int _y;
public class Polygon { private Point corners[];
}
public Point(int x, int y) { _x=x; _y=y;
}
public int getY() { return _y;
}
Polygon(int[][] points) { }
19

Polygon(int[][] points)
throws IllegalArgumentException {
if (points.length< 3) { throw new IllegalArgumentException( "Not enough corners "); } } else { corners=new Point[points.length]; for (int i=0; i 5;
class PizzaDelivery {
// …
int getRating() {
return numberOfLateDeliveries > 5 ? 2 : 1;
Inline Method
• When a method body is more obvious than the method itself.
• Eliminates code smell : Dead code (unused class, method, field etc.
class PizzaDelivery
28

• Eliminates code smell : comments
void renderBanner() {
if ((platform.toUpperCase().indexOf(“MAC”) > ‐1) && (browser.toUpperCase().indexOf(“IE”) > ‐1)
&& wasInitialized() && resize > 0 ) { // do something } }
Extract Variable
void renderBanner() {
final boolean isMacOs = platform.toUpperCase().indexOf(“MAC”) > ‐1;
final boolean isIE = browser.toUpperCase().indexOf(“IE”) > ‐1; final boolean wasResized = resize > 0;
if (isMacOs && isIE && wasInitialized() && wasResized) { // do something }
}
29

double basePrice = order.basePrice(); return basePrice > 1000;
}
Inline Temp
• You have a temporary variable that’s assigned the result of a simple expression and nothing more.
boolean hasDiscount(Order order) {
boolean hasDiscount(Order order) { return order.basePrice() > 1000;
}
30

if (basePrice > 1000) { return basePrice * 0.95; }
} else {
else {
return basePrice * 0.98;
return basePrice() * 0.98; }
} }
}
double basePrice() {
Replace Temp with Query
• If a temporary variable hold the result of an expression.
• Extract the expression into a method.
• Eliminates code smell : Long method, duplicate code
double calculateTotal() {
double calculateTotal() {
double basePrice = quantity * itemPrice;
if (basePrice() > 1000) { return basePrice() * 0.95;
return quantity * itemPrice; } 31

• Inline Class
Refactoring Techniques
• Moving Features between Objects • Move Method
• Move Field
• Extract Class
32

Move Method
• If a method on one class uses (or is used by) another class more than the class on which its defined, move it to the other class.
• Eliminates code smell : Shotgun Surgery, Feature Envy, Data Class
public class Student
{
public boolean isTaking(Course course)
{
return (course.getStudents().contains(this));
}
}
public class Course
{ public boolean isTaking(Student student) private List students;
public List getStudents()
{
return students;
}
}
public class Student {
}
public class Course {
private List students;
{
return students.contains(student); }
}
33

Move Method
34

Move Field
35

public class Customer
{
private String name;
private String workPhoneAreaCode; private String workPhoneNumber;
public class Customer
{
private String name; private Phone workPhone; }
}
public class Phone
{
private String areaCode; private String number;
Extract Class
• Break one class into two, e.g. Having the phone details as part of the Customer class is not a realistic OO model.
• Eliminate code smell : Large Class, Duplicate Code, ..
}
36

Extract Class
37

Inline Class
• Eliminate code smell : Shotgun Surgery, lazy class, oldbagage/deadcode ..
38

Refactoring Techniques
• Generalization
• Pull Up Field
• Pull Up Method
• Push Down Method
• Push Down Field
• Extract Subclass
• Extract Superclass
• Replace Inheritance with Delegation • Replace Delegation with Inheritance
39

• Eliminate code smell : Duplicate Code
Pull Up Field
40

• Eliminate code smell : Duplicate Code
Pull Up Method
41

Push Down Method
42

Push Down Field
43

Extract Subclass
• When a class has features (attributes and methods) that would only be useful in specialized instances, we can create a specialization of that class and give it those features.
• This makes the original class less specialized (i.e., more abstract), and good design is about binding to abstractions wherever possible.
44

• Eliminate code smell : Large Class
public class Person{
public class Person
{
protected String name; }
private String name;
private String jobTitle; }{
Extract Subclass
public class Employee extends Person
private String jobTitle; }
45

Extract Subclass
46

Extract Superclass
• When you find two or more classes that share common features, consider abstracting those shared features into a super‐class.
• This makes it easier to bind clients to an abstraction, and removes duplicate code from the original classes.
47

private String name; private Course course; }
public class Student extends Person {
private Course course;
}
Extract Superclass
public class Employee
{
private String name;
private String jobTitle; }{
public class Student private String jobTitle; {}
public abstract class Person {
protected String name;
}
public class Employee extends Person
48

• Eliminate code smell : Duplicate Code
Extract Superclass
49

Replace Inheritance with Delegation
50

Replace Delegation with Inheritance
51

Refactoring Techniques
• Simplifying Conditional Expressions
• Decompose Conditional
• Consolidate Conditional Expression
• Replace Nested Conditional with Guard Clauses • Replace Conditional with Polymorphism
52

• Eliminates : long method
} else {
charge = quantity * summerRate;
}
else {
}
charge = winterCharge(quantity); }
Decompose Conditional
if (date.before(SUMMER_START) || date.after(SUMMER_END)) { charge = quantity * winterRate + winterServiceCharge;
if (isSummer(date)) {
charge = summerCharge(quantity);
53

double disabilityAmount() { if (seniority < 2) { double disabilityAmount() { if (isNotEligableForDisability()) { return 0; } return 0; } if (monthsDisabled > 12) { return 0; }
if (isPartTime) { return 0;
}
// Compute the disability amount. // … }
// Compute the disability amount. // …
}
Consolidate Conditional Expression
• Eliminates : Duplicate Code
54

public double getPayAmount() { double result;
if (isDead){
result = deadAmount(); }
else {
if (isSeparated){
public double getPayAmount() { if (isDead){
result = separatedAmount(); } else {
if (isSeparated){
return separatedAmount(); }
if (isRetired){
return retiredAmount();
}
return normalPayAmount(); }
if (isRetired){
result = retiredAmount(); }
else{
result = normalPayAmount();
}
55
}
}
}
return result;
Replace Nested Conditional with Guard Clauses
return deadAmount(); }

class Bird { // …
class European extends Bird { double getSpeed() {
return getBaseSpeed();
double getSpeed() { switch (type) {
} }
Replace Conditional with Polymorphism
• Eliminates : Switch Statment
abstract class Bird { // …
case EUROPEAN: return getBaseSpeed();
case AFRICAN: return getBaseSpeed() ‐ getLoadFactor() * numberOfCoconuts;
case NORWEGIAN_BLUE:
return (isNailed) ? 0 : getBaseSpeed(voltage);
}
class African extends Bird { double getSpeed() {
throw new RuntimeException(“Should be unreachable”); }
}
class NorwegianBlue extends Bird { double getSpeed() {
}
return (isNailed) ? 0 : getBaseSpeed(voltage); }
abstract double getSpeed(); }
return getBaseSpeed() ‐ getLoadFactor() * numberOfCoconuts; }
} // Somewhere in client code speed = bird.getSpeed();
56

Summary
57

• Site : http://refactoring.com
References
• Book : Improving the Design of Existing Code (by Martin Fowler
58

• Eclipse examples
59