Introduction
Refactoring is the process of restructuring existing code without changing its external behavior. It improves code readability, reduces complexity, and makes the code easier to maintain and extend.
Extract Method
Break large methods into smaller, focused methods with descriptive names.
# Before refactoring
def process_order(order):
# Calculate total
total = 0
for item in order.items:
total += item.price * item.quantity
# Apply discount
if order.customer.is_vip:
total *= 0.9
# Calculate tax
total *= 1.1
# Save order
print(f"Saving order: {total}")
# Send confirmation
print(f"Sending email to {order.customer.email}")
# Update inventory
for item in order.items:
print(f"Decrementing {item.name}")
return total
# After refactoring
def calculate_order_total(order):
subtotal = sum(item.price * item.quantity for item in order.items)
return apply_discount(subtotal, order.customer)
def apply_discount(total, customer):
return total * 0.9 if customer.is_vip else total
def calculate_final_price(order):
return calculate_order_total(order) * 1.1
def save_order(order, total):
print(f"Saving order: {total}")
def send_order_confirmation(order):
print(f"Sending email to {order.customer.email}")
def update_inventory(order):
for item in order.items:
print(f"Decrementing {item.name}")
def process_order(order):
total = calculate_final_price(order)
save_order(order, total)
send_order_confirmation(order)
update_inventory(order)
return total
Rename Variable
Use meaningful variable names that convey intent.
# Before
def get_stats(data):
x = 0
y = 0
for i in data:
x += i["v"]
y += 1
return x / y
# After
def calculate_average_value(records):
total_value = 0
record_count = 0
for record in records:
total_value += record["value"]
record_count += 1
return total_value / record_count
Introduce Parameter Object
Group related parameters into a class or data structure.
# Before
def create_user(name, email, phone, address, city, state, zip_code):
print(f"Creating user: {name}, {email}, {phone}")
print(f"Address: {address}, {city}, {state} {zip_code}")
create_user("John", "john@email.com", "123-456-7890", "123 Main St", "Boston", "MA", "02101")
# After
class Address:
def __init__(self, street, city, state, zip_code):
self.street = street
self.city = city
self.state = state
self.zip_code = zip_code
class ContactInfo:
def __init__(self, email, phone):
self.email = email
self.phone = phone
def create_user(name, contact_info, address):
print(f"Creating user: {name}, {contact_info.email}, {contact_info.phone}")
print(f"Address: {address.street}, {address.city}, {address.state} {address.zip_code}")
contact = ContactInfo("john@email.com", "123-456-7890")
addr = Address("123 Main St", "Boston", "MA", "02101")
create_user("John", contact, addr)
Replace Conditional with Polymorphism
Use inheritance and polymorphism instead of complex conditionals.
# Before
class PaymentProcessor:
def process_payment(self, payment):
if payment.type == "credit_card":
print(f"Processing credit card: {payment.card_number}")
elif payment.type == "paypal":
print(f"Processing PayPal: {payment.email}")
elif payment.type == "bank_transfer":
print(f"Processing bank: {payment.account_number}")
return True
# After
class Payment(ABC):
@abstractmethod
def process(self):
pass
class CreditCardPayment(Payment):
def __init__(self, card_number):
self.card_number = card_number
def process(self):
print(f"Processing credit card: {self.card_number}")
class PayPalPayment(Payment):
def __init__(self, email):
self.email = email
def process(self):
print(f"Processing PayPal: {self.email}")
class BankTransferPayment(Payment):
def __init__(self, account_number):
self.account_number = account_number
def process(self):
print(f"Processing bank: {self.account_number}")
class PaymentProcessor:
def process_payment(self, payment):
return payment.process()
Practice Problems
- Extract a complex method into smaller, focused methods.
- Rename variables to be more descriptive.
- Group related parameters into a class.
- Replace a complex if-elif chain with polymorphism.
- Remove duplicate code using the Extract Method refactoring.