Refactoring
Definition

Common Refactorings
// EXTRACT METHOD: Long method → shorter, named methods
// Before
void printOwing() {
// Print banner
System.out.println("********************");
System.out.println("*** Customer Owes ***");
System.out.println("********************");
// Calculate outstanding
double outstanding = 0;
for (Order order : orders) {
outstanding += order.getAmount();
}
// Print details
System.out.println("Name: " + name);
System.out.println("Amount: " + outstanding);
}
// After
void printOwing() {
printBanner();
double outstanding = calculateOutstanding();
printDetails(outstanding);
}
private void printBanner() {
System.out.println("********************");
System.out.println("*** Customer Owes ***");
System.out.println("********************");
}
private double calculateOutstanding() {
return orders.stream()
.mapToDouble(Order::getAmount)
.sum();
}
private void printDetails(double outstanding) {
System.out.println("Name: " + name);
System.out.println("Amount: " + outstanding);
}
More Refactorings
// EXTRACT CLASS: Class doing too much
// Before
class Order {
private String customerName;
private String customerEmail;
private String customerPhone;
private List<LineItem> items;
void sendConfirmation() { /* email logic */ }
boolean validateCustomerEmail() { /* validation */ }
}
// After
class Order {
private Customer customer;
private List<LineItem> items;
}
class Customer {
private String name;
private String email;
private String phone;
void sendConfirmation() { /* email logic */ }
boolean validateEmail() { /* validation */ }
}
// REPLACE CONDITIONAL WITH POLYMORPHISM
// Before
double calculatePay(Employee e) {
switch (e.type) {
case HOURLY: return e.hours * e.rate;
case SALARIED: return e.salary / 12;
case COMMISSIONED: return e.basePay + e.sales * e.commission;
}
}
// After
abstract class Employee {
abstract double calculatePay();
}
class HourlyEmployee extends Employee {
double calculatePay() { return hours * rate; }
}
class SalariedEmployee extends Employee {
double calculatePay() { return salary / 12; }
}
class CommissionedEmployee extends Employee {
double calculatePay() { return basePay + sales * commission; }
}
Code Smells

Safe Refactoring Process

Refactoring to Patterns
// Refactoring toward design patterns
// BEFORE: Conditional logic for discounts
class Order {
double getTotal() {
double total = calculateBaseTotal();
if (customer.isGold()) {
total *= 0.85; // 15% off
} else if (customer.isSilver()) {
total *= 0.90; // 10% off
}
if (isHolidaySeason()) {
total *= 0.95; // 5% off
}
return total;
}
}
// AFTER: Strategy pattern
interface DiscountStrategy {
double apply(double total);
}
class GoldDiscount implements DiscountStrategy {
public double apply(double total) { return total * 0.85; }
}
class SilverDiscount implements DiscountStrategy {
public double apply(double total) { return total * 0.90; }
}
class HolidayDiscount implements DiscountStrategy {
public double apply(double total) { return total * 0.95; }
}
class Order {
private List<DiscountStrategy> discounts;
double getTotal() {
double total = calculateBaseTotal();
for (DiscountStrategy discount : discounts) {
total = discount.apply(total);
}
return total;
}
}
Tips & Tricks
