7
\$\begingroup\$

In the book Clean Code from Robert C. Martin are given many recommendations. Two of them are

  • to keep functions small and
  • within a function to only have one level of abstraction.

I already cleaned the following method up a bit by extracting a few methods (RemoveFontColor(), RemoveTextHighlight()). But i am not sure if the few-liners (font-style, font-weight, etc.) should be extracted into a method as well. The advise from the author is to not mix different-levels of abstraction within a function because this could lead to other details creeping in. This would mean that even the two liners will be extracted into their own methods.

The partly refactored code example

private string Fix(FixPreferences preferences,string value)
{
    if (preferences.IsRemoveBold) {
        value = value.Replace("font-weight:bold", "font-weight:normal");
        value = value.Replace("font-weight: bold", "font-weight:normal");
    }
    if (preferences.IsRemoveItalics) {
        value = value.Replace("font-style:italic;", "font-style:normal;");
        value = value.Replace("font-style: italic;", "font-style:normal;");
    }    
    if (preferences.IsRemoveFontColor) {
        value = RemoveFontColor(value);
    }
    if (preferences.IsRemoveTextHighlight) {
        value = RemoveTextHighlight(value);
    }  
    if (preferences.IsRemoveStrikethrough){
       value = 
        value.Replace("text-decoration: line-through;", "text-decoration:none;");
       value = 
        value.Replace("text-decoration:line-through;", "text-decoration:none;");
    }
    if (preferences.IsRemoveUnderline)
    {           
      value = 
       value.Replace("text-decoration: underline;", "text-decoration:none;");
      value = 
       value.Replace("text-decoration:underline;", "text-decoration:none;");
    }
    return value;
}

Update

I changed to extract even the few lines - but it still looks not pretty.

    private string Fix(ChangeLogFixOperationPreferences preferences,string value)
    {
        if (preferences.IsRemoveBold)
                value = RemoveBold(value);

        if (preferences.IsRemoveItalics)
                value = RemoveItalics(value);

        if (preferences.IsRemoveFontColor)
                value = RemoveFontColor(value);

        if (preferences.IsRemoveTextHighlight)
                value = RemoveTextHighlight(value);

        if (preferences.IsRemoveStrikethrough)
                value = RemoveStrikethrough(value);

        if (preferences.IsRemoveUnderline)
                value = RemoveUnderline(value);

        if (preferences.IsResetFontSize)
                value = ResetFontSize(value);

        return value;
    }

Is there a better way - for example to put the preferences and the methods into a dictionary and for each preference that is set to true the function from the dictionary is called within a loop?

My question

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

First of all, each condition and formatting will be moved to your own class. Let's create a common interface:

interface FormattingRemover
{
    bool Match(string value);
    string RemoveFormat(string value);
}

Now we can use it to abstract the formatting:

public class RemoveBold : FormattingRemover
{
    public bool Match(string value) {
        // your condition here
        return true;
    }

    public string RemoveFormat(string value) {
        return RemoveBold(value);
    }
}

In your class you'll need a list with all implementantions of FormattingRemover, iterate over it and when the value matches, you can remove its formatting.

private removers = AllRemovers();

private string Fix(ChangeLogFixOperationPreferences preferences,string value)
{
    foreach (var remover in removers)
    {
        if (remover.Match(value))
        {
            value = remover.RemoveFormat(value);
        }
    }

    return value;
}

For now on, you just need to add new implementations to provide it with AllRemovers. A good idea is inject it with some DI container, like Ninject.

\$\endgroup\$
2
  • \$\begingroup\$ What would be in private removers = AllRemovers(); ? Would it contain a List of all preferences (IsRemoveBold, IsRemoveUnderline, ...) which formating should be removed? \$\endgroup\$
    – surfmuggle
    Aug 6, 2013 at 14:13
  • 1
    \$\begingroup\$ AllRemovers() is a method which populate and returns a List of all implementantions of FormattingRemover. The class RemoveBold is an example of how this should be done. \$\endgroup\$ Aug 6, 2013 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.