Extract Method Refactoring Technique in C# – What You Need To Know

Extract Method Refactoring Technique in C# – What You Need To Know

The post Extract Method Refactoring Technique in C# – What You Need To Know appeared first on Dev Leader.

After coding for 20+ years, the Extract Method refactoring technique is one of the most fundamental tools we have to use when it comes to refactoring code. In my experience, I’ve refactored a lot of code — and a lot of it was code I wrote in the first place! One of the most common things we find ourselves doing when refactoring is splitting up code that’s either doing too much or not obvious work into dedicated methods. That’s the exact principle behind this technique, so let’s check it out with a C# code example!


Courses - Dometrain - Refactoring for csharp devs - wide

Click to get this course NOW!


What is the Extract Method Refactoring Technique?

Refactoring code is an important skill for software engineers, as it helps improve the readability and maintainability of our codebase. One such technique that can greatly assist us in achieving this goal is the Extract Method technique. I use this so frequently that almost immediately after I write some code I do this!

The Extract Method technique involves taking a block of code within a method and extracting it into a separate method. By doing this, we can improve the clarity and understandability of our code by breaking it down into smaller, more manageable pieces. Don’t wait until you have a 2000-line method before you figure out why this is helpful!


Extract Method Refactoring C# Code Example

To demonstrate this technique, consider the following example in C# for order processing:

public class OrderProcessing
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("Processing order...");

        // Calculate order total
        double total = 0;
        foreach (var item in order.Items)
        {
            total += item.Price * item.Quantity;
        }

        // Apply discount
        if (order.Customer.IsPremium)
        {
            total *= 0.9; // 10% discount for premium customers
        }

        // Add tax
        total *= 1.2; // Assuming a fixed tax rate of 20%

        // Print order summary
        Console.WriteLine($"Order ID: {order.Id}");
        Console.WriteLine($"Customer: {order.Customer.Name}");
        Console.WriteLine($"Total due: {total:C}");

        Console.WriteLine("Order processed.");
    }
}

In the code above, this class has a single method with several responsibilities. While I am not hyper-focused on using the Single Responsibility Principle, I do think it’s helpful as a guide. This single method handles customer orders, including calculating the order total, applying discounts, adding tax, and printing the order summary. Initially, these operations are all done within a single method, which can make the code hard to read and maintain — especially as time goes on and people come along to add more.

Let’s consider the following code where we use the Extract Method refactoring technique:

public class OrderProcesser
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("Processing order...");

        double total = CalculateOrderTotal(order);
        total = ApplyDiscount(total, order.Customer);
        total = AddTax(total);

        PrintOrderSummary(order, total);

        Console.WriteLine("Order processed.");
    }

    private double CalculateOrderTotal(Order order)
    {
        double total = 0;
        foreach (var item in order.Items)
        {
            total += item.Price * item.Quantity;
        }

        return total;
    }

    private double ApplyDiscount(double total, Customer customer)
    {
        if (customer.IsPremium)
        {
            return total * 0.9; // 10% discount for premium customers
        }

        return total;
    }

    private double AddTax(double total)
    {
        return total * 1.2; // Assuming a fixed tax rate of 20%
    }

    private void PrintOrderSummary(Order order, double total)
    {
        Console.WriteLine($"Order ID: {order.Id}");
        Console.WriteLine($"Customer: {order.Customer.Name}");
        Console.WriteLine($"Total due: {total:C}");
    }
}

In the refactored version, I have extracted methods for calculating the order total, applying discounts, adding tax, and printing the order summary. This improves readability by clearly separating concerns and increases reusability by allowing each piece of functionality to be reused independently. While minor for this simple example, hopefully, this illustrates the concept clearly!


Benefits of the Extract Method Refactoring Technique

The Extract Method technique is one of the most basic refactoring tools we have, but alone it provides us with benefits. Aside from being a building block for more involved refactoring techniques, it improves the readability of our code. By creating smaller, self-explanatory methods that focus on a single responsibility the code can become more expressive and understandable. This makes it easier for other developers to read and maintain the code. Even if the earlier example was simple, you can see that this inches us towards more of a Single Responsibility setup of our code.

Secondly, it promotes code reusability. By extracting a block of code into a separate method, we can easily reuse it in multiple places within our codebase. This reduces duplication and enforces the DRY (Don’t Repeat Yourself) principle. If we need to extend the OrderProcesser class, we can take advantage of the discount and tax calculations along with printing out the order summary if needed.

Courses - Dometrain - Refactoring for csharp devs - wide

Click to get this course now!


Scenarios Where Extract Method Refactoring is Useful

The Extract Method refactoring technique is particularly useful in scenarios where:

  1. A block of code within a method is becoming too long and complex – By extracting the code into a separate method, we can make the original method more concise and easier to understand.

  2. Common functionality needs to be reused across different methods – Extracting the common functionality into a separate method promotes code reuse and eliminates duplication.

  3. A method is responsible for multiple concerns – By extracting specific parts of the method into separate methods, we can improve the clarity and maintainability of the code.

The Extract Method refactoring technique is a fundamental refactoring technique that once you start using, it almost becomes second nature in how you’re coding. By breaking down complex methods into smaller, focused ones, we can create code that is easier to understand and maintain.


Wrapping Up Extract Method Refactoring Technique in C

Refactoring involves many tools, skills, and techniques to practice with and gain confidence in. The Extract Method refactoring technique is one of the foundational aspects of refactoring that we have to work with. We can leverage it to re-use code and to make the intention of the code more obvious by grouping logic into methods.

If you found this useful and you’re looking for more learning opportunities, consider subscribing to my free weekly software engineering newsletter and check out my free videos on YouTube! You can also check out my Discord community for more hands-on discussions!


Want More Dev Leader Content?

  • Follow along on this platform if you haven’t already!

  • Subscribe to my free weekly software engineering and dotnet-focused newsletter. I include exclusive articles and early access to videos:
    SUBSCRIBE FOR FREE

  • Looking for courses? Check out my offerings:
    VIEW COURSES

  • E-Books & other resources:
    VIEW RESOURCES

  • Watch hundreds of full-length videos on my YouTube channel:
    VISIT CHANNEL

  • Visit my website for hundreds of articles on various software engineering topics (including code snippets):
    VISIT WEBSITE

  • Check out the repository with many code examples from my articles and videos on GitHub:
    VIEW REPOSITORY

Did you find this article valuable?

Support Dev Leader by becoming a sponsor. Any amount is appreciated!