Refactorings
Safe, step-by-step techniques to clean up messy code.
61 lessons · follow them in order, or jump to what you need.
Extract Method: Turn One Giant Function into Small Named Helpers
Learn Extract Method step by step. Pull a messy block out of a long function, give it a clear name, and make your code read like a clean to-do list.
Inline Method: Remove the Shortcut That Was Never a Shortcut
Learn Inline Method step by step. When a tiny method's body is clearer than its name, fold it back into the caller and remove one useless hop from your code.
Extract Variable: Solve the Big Sum with Small Named Steps
Learn Extract Variable step by step. Break one giant, confusing expression into small named parts, just like showing your working in a maths copy.
Inline Temp: Throw Away the Rough Note You Used Only Once
Learn the Inline Temp refactoring with a simple rough-paper story, TypeScript and C# examples, safe steps, IDE shortcuts, and when not to inline a variable.
Replace Temp with Query: Ask Fresh, Don't Trust Yesterday's Chit
Learn Replace Temp with Query with a canteen story, TypeScript and C# examples, and safe steps. Turn local variables into reusable methods, one source of truth.
Split Temporary Variable: One Bucket Cannot Do Two Jobs
Learn Split Temporary Variable with a two-buckets story, TypeScript and C# examples, and safe steps. Give every variable one job and one clear, honest name.
Remove Assignments to Parameters: Never Scribble Over a Borrowed Notebook
Learn the Remove Assignments to Parameters refactoring with a borrowed notebook story, TypeScript and C# examples, and safe steps for beginners to follow.
Replace Method with Method Object: Give the Big Dish Its Own Kitchen Station
Learn Replace Method with Method Object through a wedding kitchen story, TypeScript and C# examples, and safe steps to untangle long methods for beginners.
Substitute Algorithm: Take the New Straight Road to School
Learn the Substitute Algorithm refactoring with a cycle-route story, TypeScript and Python examples, and the test-first safety rules every beginner needs.
Move Method: Shift Work to the Class Where It Truly Belongs
Learn the Move Method refactoring through a simple school story. Shift a method into the class whose data it uses most so behaviour and data stay together.
Move Field: Keep Data in the Room Where It Is Used
Learn the Move Field refactoring with an easy school story. Move a piece of data to the class that really uses it, so state and behaviour live side by side.
Extract Class: Give an Overworked Class a Helping Partner
Learn the Extract Class refactoring with a fun school office story. Split one overloaded class into two focused classes, each with a single clear job to do.
Inline Class: Merge a Class That Does Too Little
Learn the Inline Class refactoring through a school committee story. Merge a class that does too little back into its user and remove useless indirection.
Hide Delegate: Ask the Monitor, Let the Monitor Do the Running
Learn the Hide Delegate refactoring with a story about a class monitor who finds your homework for you. Stop writing chains like employee.department.manager — give the first object a simple method and hide the journey inside it. Step-by-step TypeScript and C# examples included.
Remove Middle Man: When the Peon Only Forwards, Meet the Principal Directly
Learn the Remove Middle Man refactoring with a story about a school peon who forwards every question to the principal without adding anything. When a class only forwards calls to its delegate, delete the forwarding and let clients talk to the delegate directly. Step-by-step TypeScript and C# walkthrough.
Introduce Foreign Method: The Stapler You Keep in Your Own Bag
Learn the Introduce Foreign Method refactoring with a story about a school photocopy machine that has no stapler. When a class you cannot modify is missing a method, write that method in your own class with the foreign object as a parameter. TypeScript and modern C# extension-method examples included.
Introduce Local Extension: Build a Cabin Next to the Rented Shop
Learn the Introduce Local Extension refactoring with a story about building an attached cabin beside a rented shop you cannot modify. When a locked class is missing many methods, gather them into one extension type — a subclass, a wrapper, or a modern C#/Kotlin extension class. Full TypeScript and C# walkthrough.
Self Encapsulate Field: Let One Gatekeeper Guard Your Data
Self Encapsulate Field explained simply — why a class should read and write its own fields through getters and setters, with safe steps, TypeScript and C# examples.
Replace Data Value with Object: Give Your Data a Proper Home
Replace Data Value with Object explained simply — how to grow a plain string or number into a small class with validation and behaviour, with TypeScript and C# record examples.
Change Value to Reference: One Office File, Not Twenty Photocopies
Change Value to Reference explained simply — why duplicate copies of the same entity go stale, and how a shared single instance via a registry or repository keeps data consistent.
Change Reference to Value: Any ₹10 Note Is As Good As Another
Change Reference to Value explained simply — how to turn a shared, mutable reference object into a small immutable value object with content-based equality, with TypeScript and C# record examples.
Replace Array with Object: Give Every Slot a Name
Replace Array with Object explained simply — why an array with secret positions like row[0], row[1], row[2] causes bugs, and how a class with named fields makes the code honest and safe.
Encapsulate Field: Let the Object Guard Its Own Data
Encapsulate Field explained simply — why public fields let any code corrupt an object's data, and how private fields with getters and setters put the object back in charge.
Encapsulate Collection: Stop Handing Out the Live List
Encapsulate Collection explained simply — why returning a live array or list lets any caller corrupt your object, and how read-only views plus add/remove methods restore control.
Replace Type Code with Class: Give Every Magic Number a Proper Badge
Learn the Replace Type Code with Class refactoring with a school house story, before/after TypeScript, C# smart enums, and a clear guide on when to pick Class, Subclasses, or State/Strategy.
Replace Type Code with Subclasses: When Each Kind Truly Behaves Differently
Learn the Replace Type Code with Subclasses refactoring with a day-scholar/boarder/hosteller story, switch-removal in TypeScript and C#, and the decision guide for Class vs Subclasses vs State/Strategy.
Replace Type Code with State/Strategy: When the Type Itself Can Change
Learn the Replace Type Code with State/Strategy refactoring with a prepaid-to-postpaid SIM story, swappable plan objects in TypeScript and C#, and the decision guide for Class vs Subclasses vs State/Strategy.
Decompose Conditional: Turn a Confusing Rule into a Simple Name
Learn the Decompose Conditional refactoring with a school circular story, simple TypeScript and C# examples, safe steps, and handy IDE shortcuts for beginners.
Consolidate Conditional Expression: Many Small Checks, One Clear Question
Learn the Consolidate Conditional Expression refactoring with a school-gate story, TypeScript and C# examples, safe steps, and the side-effect rule beginners must know.
Consolidate Duplicate Conditional Fragments: Move the Dessert Counter Outside
Learn the Consolidate Duplicate Conditional Fragments refactoring with a canteen story, TypeScript and C# examples, safety rules, and easy step-by-step practice.
Remove Control Flag: Stop Searching Once You Have Found It
Learn the Remove Control Flag refactoring with a watchman story, TypeScript and C# examples, break and return steps, plus the single-exit debate explained simply.
Replace Nested Conditional with Guard Clauses: Flatten the Arrow
Learn the Replace Nested Conditional with Guard Clauses refactoring with a temple queue story, early returns that flatten arrow-shaped code, and safe step-by-step mechanics in TypeScript and C#.
Replace Conditional with Polymorphism: Give Every Kind Its Own Desk
Learn the Replace Conditional with Polymorphism refactoring with a school reception story, repeated type switches dissolving into subclasses, a factory in TypeScript and C#, and honest advice on when a plain switch is fine.
Introduce Null Object: Give 'Nothing' a Polite Stand-In
Learn the Introduce Null Object refactoring with a school guardian-card story, Tony Hoare's billion-dollar mistake, scattered null checks replaced by one well-behaved default object, and honest advice on when null objects hide bugs.
Introduce Assertion: Taste the Dal Before You Serve It
Learn the Introduce Assertion refactoring with a careful cook's story, hidden assumptions turned into executable checks, Debug.Assert in C# and asserts functions in TypeScript, and the crucial difference between assertions and input validation.
Rename Method: Fix the Shop Board So It Tells the Truth
Rename Method explained simply — why a method's name must say what the method really does, how to rename safely with a delegating old method, and how IDEs like VS Code (F2) and JetBrains (Shift+F6) make it a one-key job.
Add Parameter: One More Detail on the Tiffin Order Slip
Add Parameter explained simply — how to give a method a new piece of information it now needs, why an explicit parameter beats hidden global state, how to do it safely with overloads, and when to stop before the parameter list grows too long.
Remove Parameter: Delete the 'Telegram Address' Field from the School Form
Remove Parameter explained simply — how to safely delete a parameter the method no longer uses, why dead parameters mislead readers and burden every caller, and the checks (interfaces, overrides, reflection) you must do before deleting.
Separate Query from Modifier: Asking Your Bill Must Not Add Chai to It
Separate Query from Modifier explained simply — split a method that both answers a question and changes state into a pure query and a separate command, following Bertrand Meyer's Command-Query Separation principle: asking a question should not change the answer.
Parameterize Method: One Juice Recipe with a Size Input
Learn the Parameterize Method refactoring with a juice stall story, TypeScript and C# examples, safe step-by-step mechanics, and the seesaw rule that pairs it with Replace Parameter with Explicit Methods.
Replace Parameter with Explicit Methods: Name Boards Instead of Secret Codes
Learn the Replace Parameter with Explicit Methods refactoring with a bank counter story, TypeScript and Python examples, safe mechanics, and the seesaw rule that pairs it with Parameterize Method.
Preserve Whole Object: Show the Whole ID Card
Learn the Preserve Whole Object refactoring with a school ID card story, TypeScript and C# examples, safe step-by-step mechanics, and an honest look at the coupling cost of passing whole objects.
Replace Parameter with Method Call: Don't Tell the Shopkeeper His Own Prices
Learn the Replace Parameter with Method Call refactoring (Replace Parameter with Query in Fowler's 2nd edition) with a kirana shop story, TypeScript and C# examples, safe mechanics, and the testability fine print.
Introduce Parameter Object: Hand Over One Address Card, Not Five Answers
Introduce Parameter Object explained simply — why the same group of parameters travelling together through many methods is a hidden concept, and how bundling them into one named object shortens signatures, stops order mistakes, and attracts behaviour.
Remove Setting Method: Some Things Are Written in Ink, Not Pencil
Remove Setting Method explained simply — why a field that should never change after construction must not have a setter, and how read-only fields, init-only properties, and records turn 'please don't change this' into a compiler guarantee.
Hide Method: The Secret Masala Stays Inside the Kitchen
Hide Method explained simply — why a method that only the class itself uses should not sit on the public menu, and how lowering visibility to private or internal shrinks the API, protects internals, and frees you to change code without fear.
Replace Constructor with Factory Method: Order a Named Thali, Let the Kitchen Decide
Learn the Replace Constructor with Factory Method refactoring with a thali restaurant story, before/after TypeScript and C#, safe step-by-step migration, and a clear comparison with the full Factory Method design pattern.
Replace Error Code with Exception: Stop Whispering Failures, Announce Them
Learn the Replace Error Code with Exception refactoring with a government-office story, before/after TypeScript and C#, safe migration steps, and an honest comparison with Result types as the modern third way.
Replace Exception with Test: Read the Board Before You Walk In
Learn the Replace Exception with Test refactoring (Replace Exception with Precheck) with a canteen story, before/after TypeScript and C#, TryParse-style patterns, the check-then-act race-condition trap, and Result types as the modern third way.
Pull Up Field: One Notice Board for Information Everyone Shares
Learn the Pull Up Field refactoring with a school notice-board story — move a field that every subclass duplicates into the superclass, with safe steps in TypeScript and C#, IDE support, and the pull-up vs push-down direction guide.
Pull Up Method: One Instruction Sheet for the Whole School
Learn the Pull Up Method refactoring with a school leave-application story — move methods duplicated across subclasses into the superclass, with safe steps in TypeScript and C#, IDE dialogs, and when to choose Form Template Method instead.
Pull Up Constructor Body: One Shared Morning Routine, Then Your Own First Period
Learn the Pull Up Constructor Body refactoring with a school morning-assembly story — move duplicated initialization from subclass constructors into a superclass constructor called via super/base, with safe steps in TypeScript and C#.
Push Down Field: Swimming Pool Timings Belong on 7C's Board Only
Learn the Push Down Field refactoring with a school notice-board story — move a superclass field that only some subclasses use down into exactly those subclasses, with safe steps in TypeScript and C#, IDE dialogs, and the pull-up vs push-down compass.
Push Down Method: Move a Method to the Subclass That Really Uses It
Learn the Push Down Method refactoring with a school-office story, honest superclass contracts, safe step-by-step moves in TypeScript and C#, and how it cures the Refused Bequest smell.
Extract Subclass: Give the Special Case Its Own Class
Learn the Extract Subclass refactoring with a tailor-shop story about urgent orders, flag-removal in TypeScript and C#, safe step-by-step moves, and when subclassing is the wrong tool.
Extract Superclass: One Common Rulebook for Twin Classes
Learn the Extract Superclass refactoring with a science-lab/computer-lab story, pull-up moves in TypeScript and C#, the superclass-vs-interface decision table, and how it removes Duplicate Code.
Extract Interface: One Common Form, Many Different Workers
Learn the Extract Interface refactoring with a visitor-register story about an electrician and a plumber, contract-extraction in TypeScript and C#, test doubles, and the interface-vs-superclass decision table.
Collapse Hierarchy: When Parent and Child Classes Become the Same
Learn the Collapse Hierarchy refactoring with a housing-society committee story, step-by-step merging of a superclass and subclass in TypeScript and C#, and the checks that tell you when a hierarchy has stopped earning its keep.
Form Template Method: One Recipe Card, Many Biryanis
Learn the Form Template Method refactoring with a two-aunties biryani story, step-by-step extraction of a shared algorithm skeleton in TypeScript and Python, and how this refactoring produces the Template Method design pattern.
Replace Inheritance with Delegation: Rent the Counter, Don't Inherit the Shop
Learn the Replace Inheritance with Delegation refactoring with a sweet-shop inheritance story, the honest meaning of composition over inheritance, the fragile base class problem, and step-by-step conversion in TypeScript and C#.
Replace Delegation with Inheritance: When the Helper Should Become the Apprentice
Learn the Replace Delegation with Inheritance refactoring with a tailor-shop helper story, the Middle Man smell, the strict is-a conditions that must hold first, and step-by-step conversion in TypeScript and C#.