If your code could talk, it might scream:
“Why did you leave me like this?! Why did you name me like this?”
Read-Rename-Reshape is the therapy it needs. Think of messy code like an overgrown garden. You can’t just plant new flowers without trimming, labeling, and organizing the paths.
Most developers just jump into the code when they want to refactor. But think of code as a conversation. You are hearing one that doesn’t make sense to you. Do you jump blindly into it? Or do you first make the meaning clear, then guide the conversation in the right direction?

Code, whether it’s a conversation or a feature requested by a product manager and implemented by a software engineer, behaves the same way. Read-Rename-Reshape is a simple yet powerful technique I use whenever I want to improve any piece of code in any programming language. You can combine R³ with other refactoring techniques to amplify their effect.
It has three steps:
Read
Before changing any code, start by reading it carefully. Pair with the original author if possible, or discuss the feature with a product person.
Your goal is to understand the conversation encoded in the code. The code contains hypotheses, implicit assumptions, intentions, and expectations.
Think of this step as wearing a learning helmet: absorb everything, ask questions, don’t assume.
// Messy example
public decimal Calc(Order o, decimal d, decimal t)
{
if(o.BasePrice < 0) throw new Exception("oops");
var result = o.BasePrice - d + t;
// just for the sake of simplicity!
Console.WriteLine("total: " + result);
return result;
}
There are a couple of smells you might detect here:
- Primitive obsession: d and t as decimals instead of proper discount/tax objects
- Unclear naming: Calc doesn’t explain what’s being calculated
- Long method / multi-purpose: prints and calculates in the same function
- Hidden assumptions: Is o.BasePrice ever negative? Are d and t guaranteed to be valid?
- Potential repetition: this calculation may appear elsewhere
Also ask questions like the following:
- What assumptions exist about Discount and Tax?
- What happens if order.BasePrice is negative?
- Is the calculation repeated elsewhere?
Reading messy code is like decoding someone else’s thoughts, before touching anything, understand the conversation first.
Rename
All code is just a collection of names—for variables, functions, classes, and modules. Renaming is your first tool to encode your understanding into the code.
- Start with high-level abstractions: methods, classes, or services.
- Then move to smaller entities: variables, parameters, and internal fields.
Why start abstract? Because renaming higher-level concepts bubbles up positive effects throughout the code. Every method call or variable that uses these names becomes easier to understand automatically.
// Before
public decimal Calc(Order o) {...}
// After
public decimal CalculateTotalPriceWithTax(Order order) {...}
Commit after each meaningful rename. It helps track changes clearly and reduces risk.
Reshape
Finally, reshape the code. This is where you reorganize, extract, simplify, or restructure. Reshape should be small and incremental. Don’t rewrite the whole class, focus on one logical unit at a time.
- Extract methods for repeated logic
- Introduce small helper functions
- Simplify conditionals or loops
- Reorder code to follow flow of reading
// Before
public decimal CalculateTotalPriceWithTax(Order order)
{
var basePrice = order.BasePrice;
var discount = order.Discount;
var tax = order.Tax;
if (tax > 25000) tax = 25000;
return basePrice - discount + tax;
}
// After (reshaped)
public decimal CalculateTotalPriceWithTax(Order order)
{
var discountedPrice = ApplyDiscount(order.BasePrice, order.Discount);
var cappedTax = CapTax(order.Tax);
return discountedPrice + cappedTax;
}
private decimal ApplyDiscount(decimal basePrice, decimal discount) => basePrice - discount;
private decimal CapTax(decimal tax) => Math.Min(tax, 25000);
Reshape ensures readability, maintainability, and correctness. Each small improvement compounds into a more robust and understandable codebase.
Short List of Tips for Practicing R³
- Always commit after each rename or reshape.
- Pair programming helps clarify intent during Read.
- Don’t mix multiple logical units in a single Reshape.
- Combine with unit tests and contracts for safety.
R³ is not just a refactoring pattern; it’s a mindset. Start by understanding, clarify with names, and then reshape with care. Over time, your code will read like a conversation that makes sense, for you, your team, and your future self.
Leave a Reply