The Natural Order of Refactoring Under the Microscope Part 3: Extract Method

Table of Contents

Analyzing Class and Method Responsibilities

In the next step, we examine the responsibilities of individual classes and methods, checking if they align with the intended responsibility of the class. It is best to analyze all methods and group them based on performing similar operations. We look for a place for these in other classes or a new class. Remember: if there is a significant private method in a class (longer than 3-4 lines), it should be moved to another class.

Example: Extracting Methods for Clarity

In our example, the methods mainly revolve around discrete operations aimed at obfuscating text and ensuring operations are performed with a certain probability. We can extract classes corresponding to these operations: TextObfuscatorMethods and Probability.

Refactored Code Example

The code after this change might look like this:

public class TextObfuscator
{
    // ...
    public string Obfuscate(string text)
    {
        List<TextPart> parts = methods.ParseTextForWordsAndNonWords(text);
        methods.ChangeWordsOrderRandomly(parts);
        methods.AddMeaninglessWordsRandomly(parts);
        methods.RemoveSeparators(parts);
        methods.AddSeparatorsRandomly(parts);
        methods.RemoveSpaces(parts);
        // ...
    }
}

public class TextObfuscatorMethods
{
    // ...
    public virtual void RemoveSpaces(List<TextPart> parts)
    {
        for (int i = 0; i < parts.Count; i++)
        {
            RemoveSpacesFromTextPart(parts, i);
            RemoveTextPartIfEmpty(parts, i);
        }
    }

    private static void RemoveSpacesFromTextPart(List<TextPart> parts, int i)
    {
        parts[i] = parts[i].ReplaceContents(" ", "");
    }

    public virtual void RemoveSeparators(List<TextPart> parts)
    {
        for (int i = 0; i < parts.Count; i++)
        {
            RemoveSeparatorsFromTextPart(parts, i);
            RemoveTextPartIfEmpty(parts, i);
        }
    }

    public virtual void AddSeparatorsRandomly(List<TextPart> parts)
    {
        for (int i = 0; i < parts.Count; i++)
        {
            if (ShouldAddSeparator())
            {
                parts.Insert(i, TextPart.NewSeparator(DrawSeparator())); i++;
            }
        }
    }

    private bool ShouldAddSeparator()
    {
        return probability.ShouldBeDone(ADDING_SEPARATOR_PROBABILITY);
    }
    // ...
}

public class Probability
{
    private Random random = new Random();

    public bool ShouldBeDone(double probability)
    {
        if (probability < 0.0 || probability > 1.0)
        {
            throw new ProbabilityException("Probability should be in range [0.0, 0.1]");
        }

        return random.NextDouble() < probability;
    }
}

This refactoring approach helps to maintain a clean codebase by ensuring that each class has a single responsibility and methods are organized according to their functionalities.

(Text translated and moved from original old blog automatically by AI. May contain inaccuracies.)

Related Posts

Antipattern: Adrenaline Junkie

Antipattern: Adrenaline Junkie

Understanding Project Pressure and Tension

I constantly wonder why situations arise where pressure and tension are generated in projects. One reason is that most projects are simply complex—you have to coordinate several, sometimes dozens of people, anticipate and plan in advance what will happen, and determine what resources will be needed. As a species, we’re not very good at detailed long-term planning (see: David Rock – Your Brain at Work).

Read More

Why Agile Fails

Introduction

Implementing a methodology from the Agile family is not at all easy. The problem usually lies in management, who upon superficially understanding what it’s all about, perceive the new method as a promise that from now on, everything will magically work better. It doesn’t matter if we have subpar team members and adhere to the principle that “any specialist can be replaced by a finite number of students.” It doesn’t matter if there’s complete disregard for knowledge management and skill development in the team because there’s never time for that. It doesn’t matter if people working on projects are shuffled between projects—after all, it’s about interdisciplinarity, and everyone should know everything.

Read More

Clients Want to Be Agile...

Clients Want to Be Agile…

One of the recent meetings involved establishing (by me, MS) a way to collaborate with a client (details intentionally slightly modified or omitted, though based on a real case). The client (K) said:

Read More