# Extract Method
Problem
//You have a code fragment that can be grouped together.
void printOwing() {
printBanner();
// Print details.
System.out.println("name: " + name);
System.out.println("amount: " + getOutstanding());
}
Solution
//Move this code to a separate new method (or function) and replace the old code with a call to the method.
void printOwing() {
printBanner();
printDetails(getOutstanding());
}
void printDetails(double outstanding) {
System.out.println("name: " + name);
System.out.println("amount: " + outstanding);
}
# Replace Temp with Query
Problem
//You place the result of an expression in a local variable for later use in your code.
double calculateTotal() {
double basePrice = quantity * itemPrice;
if (basePrice > 1000) {
return basePrice * 0.95;
}
else {
return basePrice * 0.98;
}
}
Solution
//Move the entire expression to a separate method and return the result from it. Query the method instead of using a variable. Incorporate the new method in other methods, if necessary.
double calculateTotal() {
if (basePrice() > 1000) {
return basePrice() * 0.95;
}
else {
return basePrice() * 0.98;
}
}
double basePrice() {
return quantity * itemPrice;
}
# Introduce Parameter Object
# PreServe Whole Object
Problem
//You get several values from an object and then pass them as parameters to a method.
int low = daysTempRange.getLow();
int high = daysTempRange.getHigh();
boolean withinPlan = plan.withinRange(low, high);
Solution
//Instead, try passing the whole object.
boolean withinPlan = plan.withinRange(daysTempRange);
# Replace Method with Method Object
Problem
//You have a long method in which the local variables are so intertwined that you cannot apply Extract Method.
class Order {
// ...
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// Perform long computation.
}
}
Solution
//Transform the method into a separate class so that the local variables become fields of the class. Then you can split the method into several methods within the same class.
class Order {
// ...
public double price() {
return new PriceCalculator(this).compute();
}
}
class PriceCalculator {
private double primaryBasePrice;
private double secondaryBasePrice;
private double tertiaryBasePrice;
public PriceCalculator(Order order) {
// Copy relevant information from the
// order object.
}
public double compute() {
// Perform long computation.
}
}
# Decompose Conditional
Problem
//You have a complex conditional (if-then/else or switch).
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
charge = quantity * winterRate + winterServiceCharge;
}
else {
charge = quantity * summerRate;
}
Solution
//Decompose the complicated parts of the conditional into separate methods: the condition, then and else.
if (isSummer(date)) {
charge = summerCharge(quantity);
}
else {
charge = winterCharge(quantity);
}
//Using Descriptive method name
public void removeUserInfo()
public void checkUserInfoEligible()
A class contains many fields/methods/lines of code.
# Extract Class
*** # Extract Subclass***
Problem
A class has features that are used only in certain cases.
Solution
Create a subclass and use it in these cases.
# Extract Interface
Problem
Multiple clients are using the same part of a class interface. Another case: part of the interface in two classes is the same.
Solution
# Duplicate Observed Data
Problem
Is domain data stored in classes responsible for the GUI?
Solution
Then it is a good idea to separate the data into separate classes, ensuring connection and synchronization between the domain class and the GUI.
# Replace type code with class
Problem
A class has a field that contains type code. The values of this type are not used in operator conditions and do not affect the behavior of the program.
Solution
Create a new class and use its objects instead of the type code values.
# Replace type code with subclass
Problem
You have a coded type that directly affects program behavior (values of this field trigger various code in conditionals).
Solution
Create subclasses for each value of the coded type. Then extract the relevant behaviors from the original class to these subclasses. Replace the control flow code with polymorphism.
# Replace Type Code with State/Strategy
Problem
You have a coded type that affects behavior but you cannot use subclasses to get rid of it.
Solution
Replace type code with a state object. If it is necessary to replace a field value with type code, another state object is “plugged in”.
# Replace Array with Object
Problem
You have an array that contains various types of data.
String[] row = new String[2];
row[0] = "Liverpool";
row[1] = "15";
Solution
Replace the array with an object that will have separate fields for each element.
Performance row = new Performance();
row.setName("Liverpool");
row.setWins("15");
# Replace Parameter with method call
Problem
Before a method call, a second method is run and its result is sent back to the first method as an argument. But the parameter value could have been obtained inside the method being called.
int basePrice = quantity * itemPrice;
double seasonDiscount = this.getSeasonalDiscount();
double fees = this.getFees();
double finalPrice = discountedPrice(basePrice, seasonDiscount, fees);
Solution
Instead of passing the value through a parameter, place the value-getting code inside the method.
int basePrice = quantity * itemPrice;
double finalPrice = discountedPrice(basePrice);
# Preserve Whole Object
Problem
You get several values from an object and then pass them as parameters to a method.
int low = daysTempRange.getLow();
int high = daysTempRange.getHigh();
boolean withinPlan = plan.withinRange(low, high);
Solution
Instead, try passing the whole object.
boolean withinPlan = plan.withinRange(daysTempRange);
# Introduce Parameter Object
Problem
Your methods contain a repeating group of parameters.
Solution
Replace these parameters with an object.
pls refer to Extract Class, Introduce Parameter Object, Preserve Whole Object