| name | Refactoring |
| description | Systematic improvement of existing code without changing external behavior |
| category | software-development |
Refactoring
What I do
I provide techniques for improving the structure of existing code while preserving its functionality. Refactoring is the art of transforming code into a better version of itself—cleaner, simpler, more maintainable—without altering what the code does. I help identify code smells, apply transformation patterns, and ensure that improvements don't introduce regressions.
When to use me
Refactor when adding new features, fixing bugs, or during code reviews when you notice opportunities for improvement. Apply the "Rule of Three" — code can be copied once, but the third time needs refactoring. Refactor when code is hard to understand, when tests are difficult to write, or when you see duplication. Never refactor without tests that verify behavior. Avoid refactoring production code without proper safeguards.
Core Concepts
- Code Smells: Indicators of deeper problems in code
- Composition over Inheritance: Favor flexible object composition
- Extract Method: Moving code into well-named functions
- Rename Variable: Giving variables meaningful names
- Inline Method: Simplifying overly abstracted code
- Replace Conditional with Polymorphism: Using objects instead of switches
- Introduce Parameter Object: Grouping related parameters
- Replace Magic Numbers: Using named constants
- Move Method/Field: Placing functionality in appropriate classes
- Tease Apart Inheritance: Separating responsibilities in class hierarchies
Code Examples
Extract Method Refactoring
def process_order(order_data: dict) -> dict:
if "customer_id" not in order_data:
raise ValueError("Missing customer_id")
if "items" not in order_data or not order_data["items"]:
raise ValueError("Order must have items")
subtotal = 0
for item in order_data["items"]:
subtotal += item["price"] * item["quantity"]
tax = subtotal * 0.08
total = subtotal + tax
if "discount_code" in order_data:
discount = 0.1 if order_data["discount_code"] == "SAVE10" else 0
total *= (1 - discount)
order_data["order_id"] = generate_order_id()
order_data["subtotal"] = subtotal
order_data["tax"] = tax
order_data["total"] = total
order_data["status"] = "processed"
send_email(order_data[], , order_data)
order_data
() -> :
validate_order(order_data)
calculate_order_prices(order_data)
apply_discounts(order_data)
finalize_order(order_data)
send_order_notification(order_data)
order_data
() -> :
order_data:
ValueError()
order_data order_data[]:
ValueError()
() -> :
subtotal = (item[] * item[] item order_data[])
order_data[] = subtotal
order_data[] = subtotal *
order_data[] = subtotal *
() -> :
order_data order_data[] == :
order_data[] *=
order_data[] =
() -> :
order_data[] = generate_order_id()
order_data[] =
() -> :
send_email(order_data[], , order_data)
() -> :
uuid
(uuid.uuid4())[:]
Replace Conditional with Polymorphism
from abc import ABC, abstractmethod
from datetime import datetime
class Employee:
def __init__(self, name: str, employee_type: str, salary: float = 0):
self.name = name
self.employee_type = employee_type
self.base_salary = salary
def calculate_pay(self, hours_worked: float) -> float:
if self.employee_type == "hourly":
return hours_worked * self.base_salary
elif self.employee_type == "salaried":
return self.base_salary / 12
elif self.employee_type == "commission":
return self.base_salary * 0.1
class Employee(ABC):
def __init__(self, name: str):
self.name = name
() -> :
():
():
().__init__(name)
.hourly_rate = hourly_rate
() -> :
hours_worked * .hourly_rate
():
():
().__init__(name)
.annual_salary = annual_salary
() -> :
.annual_salary /
():
():
().__init__(name)
.base_salary = base_salary
() -> :
.base_salary *
Introduce Parameter Object
from dataclasses import dataclass
from typing import NamedTuple
def create_report(
title: str,
author: str,
date_created: str,
start_date: str,
end_date: str,
include_charts: bool,
include_summary: bool,
format: str,
template: str,
output_path: str
) -> None:
print(f"Creating report: {title}")
class ReportConfig(NamedTuple):
title: str
author: str
date_created: str
class DateRange(NamedTuple):
start_date: str
end_date: str
class ReportOptions(NamedTuple):
include_charts: bool = True
include_summary: bool = True
format: str = "pdf"
template: str = "default"
class ():
output_path:
() -> :
()
Replace Magic Numbers with Constants
class Order:
def __init__(self, items: list):
self.items = items
def calculate_discount(self, order_value: float, customer_age: int) -> float:
if order_value > 100:
discount = 0.1
elif order_value > 50:
discount = 0.05
else:
discount = 0
if customer_age > 65:
discount += 0.05
return order_value * discount
def is_expired(self, order_date: str) -> bool:
from datetime import datetime, timedelta
date = datetime.strptime(order_date, "%Y-%m-%d")
return datetime.now() - date > timedelta(30)
class Order:
FREE_SHIPPING_THRESHOLD = 100.0
STANDARD_DISCOUNT_RATE = 0.05
PREMIUM_DISCOUNT_RATE = 0.1
SENIOR_DISCOUNT_RATE = 0.05
ORDER_EXPIRY_DAYS = 30
def __init__(self, items: ):
.items = items
() -> :
order_value >= .FREE_SHIPPING_THRESHOLD:
discount_rate = .PREMIUM_DISCOUNT_RATE
order_value >= .FREE_SHIPPING_THRESHOLD / :
discount_rate = .STANDARD_DISCOUNT_RATE
:
discount_rate =
customer_age >= :
discount_rate += .SENIOR_DISCOUNT_RATE
order_value * discount_rate
() -> :
datetime datetime, timedelta
date = datetime.strptime(order_date, )
datetime.now() - date > timedelta(.ORDER_EXPIRY_DAYS)
Inline Method and Rename
class Account:
def __init__(self, balance: float):
self.balance = balance
def x(self) -> bool:
return self.balance > 100
def do_stuff(self, amount: float) -> None:
if self.x():
self.balance -= amount
class Account:
MINIMUM_BALANCE = 100.0
def __init__(self, balance: float):
self.balance = balance
def has_minimum_balance(self) -> bool:
return self.balance >= self.MINIMUM_BALANCE
def withdraw(self, amount: float) -> None:
if self.has_minimum_balance():
self.balance -= amount
Best Practices
- Have Tests First: Never refactor without tests that verify behavior
- Small Steps: Make small changes and run tests frequently
- One Change at a Time: Focus on one refactoring per iteration
- Use IDE Tools: Leverage automated refactoring tools
- Don't Change Behavior: Refactor structure, not functionality
- Watch for Code Smells: Duplication, long methods, large classes
- Follow the Rule of Three: Third time you copy, refactor
- Refactor When Adding Features: Clean code makes adding features easier
- Review Changes: Use pull requests for refactoring work
- Document Intent: Why something was refactored matters
- Prefer Composition: Move toward flexible object composition
- Keep Functions Small: Extract logic into named methods