The Natural Order of Refactoring Under the Microscope Part 1

Table of Contents

Refactoring is an age-old problem—perhaps not the best word given the relatively short existence of software engineering as a discipline. Everyone knows refactoring should be done, but nobody seems to have the time for it.

Once you start refactoring, it’s often not enough to just refactor for the sake of it, as it’s easy to fall into a frenzy of refactoring everything at all costs. Here, I’ll present a refactoring strategy that allows for a systematic approach to this often thankless task, contributing to the evolutionary development of a project and architecture, while also suggesting how to tackle legacy code. Here are the magic points:

  1. Start Simple: Begin with a simple solution, following the principle of “Keep it simple stupid.” Don’t overthink patterns or introduce unnecessary flexibility.

  2. Extract Methods: Start extracting smaller components from large methods (refactoring known as Extract Method). Aim for the Compose Method pattern—let your main method consist of a series of smaller method calls.

  3. Analyze Class Responsibilities: When your classes consist of many small methods, start analyzing the responsibility of each class. Move methods that fulfill different responsibilities to more appropriate classes.

  4. Introduce Design Patterns: Over time, you may notice a need for flexibility in your solutions—start introducing design patterns where needed.

  5. Regularly Review Architecture: Occasionally (every few months for larger projects), analyze what’s happening with your project. Architecture requires regular refreshing and modifications to align with emerging requirements.

The idea was illustrated in a blog post here.

Let’s assume we have a class providing a method for obfuscating text, which is a parameter of the method. Here is a sample code snippet:

public class TextManager
{
    private TextManagerHelper _hlp = null;
    // ...
    public TextManager(TextManagerHelper helper)
    {
        this._hlp = helper;
    }

    private Random rnd = new Random();

    public string Convert(string text)
    {
        String result = "";
        List<TextPart> prts = _hlp.Convert(text);

        for (int i = 0; i < prts.Count; i++)
        {
            if (prts[i].Type.Equals(TextPartType.WORD) && rnd.NextDouble() < 0.2)
            {
                if (i + 2 < prts.Count)
                {
                    TextPart t = prts[i];
                    prts[i] = prts[i + 2];
                    prts[i + 2] = t;
                }
            }
        }

        for(int i1 = 0; i1 < prts.Count; i1++)
        {
            if (rnd.NextDouble() < 0.2)
            {
                prts.Insert(i1, new TextPart(" ", TextPartType.NONWORD)); i1++;
                String[] wds = new String[] { "i", "a", "aczkolwiek", "poniekąd" };
                int ind = rnd.Next(wds.Length);
                prts.Insert(i1, new TextPart(wds[ind], TextPartType.WORD)); i1++;
                prts.Insert(i1, new TextPart(" ", TextPartType.NONWORD));
            }
        }

        String result2 = "";

        foreach (TextPart part in prts)
        {
            result2 += part.Contents;
        }

        result = result2;
        result = Regex.Replace(result, @"[\?!-\.,:;'\(\)]", "", RegexOptions.CultureInvariant);

        String result1 = "";

        for ( int i2 = 0; i2 < result.Split(' ').Length - 1; i2++)
        {
            if (rnd.NextDouble() < 0.5)
            {
                char [] chs = new char[] { '.', ',', '!' };
                int j = rnd.Next(chs.Length);
                result1 += result.Split(' ')[i2] + chs[j];
            }
            else
            {
                result1 += result.Split(' ')[i2] + " ";
            }
        }
        result1 += result.Split(' ')[result.Split(' ').Length - 1];
        result = result1;

        result = result
            .Replace("ą", "a")
            .Replace("ł", "l")
            .Replace("ę", "e")
            .Replace("ń", "n")
            .Replace("ż", "z")
            .Replace("ź", "z")
            .Replace("ó", "o")
            .Replace("ś", "s")
            .Replace("ć", "c")
            .Replace("Ą", "A")
            .Replace("Ł", "L")
            .Replace("Ę", "E")
            .Replace("Ń", "N")
            .Replace("Ż", "Z")
            .Replace("Ź", "Z")
            .Replace("Ó", "O")
            .Replace("Ś", "S");

        String result3 = "";
        char[] tArray = result.ToCharArray();

        foreach (char ch in tArray) {
            if (rnd.NextDouble() < 0.3)
            {
                char? newCh = null;
                if (Char.IsLower(ch))
                {
                    newCh = Char.ToUpper(ch);
                } else
                {
                    newCh = Char.ToLower(ch);
                }

                result3 += newCh;
            }
            else
            {
                result3 += ch;
            }
        }

        result = result3.Replace(" ", "");

        return result;
    }
}

To be continued…

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

Related Posts

Disappointment, Focus, and Solutions for All Problems ;-)

Introduction

Many of us dream of a situation where we can work at a sustainable pace, having enough time for everything and being able to comfortably do our job. But it doesn’t work. I’ll tell you why.

Read More

Code Cleanliness: More Than Just Refactoring Part 1

Initially, my intention was to create an article about refactoring. However, the more I pondered the subject, the clearer it became that I would not be writing solely about refactoring. It’s about something much more significant—conveying a vast amount of knowledge, essentially experience, related to code creation. Code that not only works or is well-designed but is most importantly easy to read. When we achieve this skill, we stand on the threshold of professionalism. Programming professionalism.

Read More

Code Cleanup: Not Just About Refactoring Part 3

Introduction

Due to formatting issues on the blogspot, it is advisable to read this article as a PDF file. You can download the PDF version of the article here.

Read More