HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Refactor embedded switch

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
embeddedswitchrefactor

Problem

A particular application may refer to a specific property in one of three languages in different contexts: in lowercase English, in uppercase English, and in Hebrew. To facilitate ease of converting one language to another, this monstrosity exists:

public string translatePersonType(string personType, string lang)
{

    switch (personType)
    {
        case "employee":
        case "EMPLOYEE":
        case "עובד":
            switch (lang)
            {
                case "eng":
                    return "employee";
                case "ENG":
                    return "EMPLOYEE";
                case "heb":
                    return "עובד";
            }
            break;

        case "contractor":
        case "CONTRACTOR":
        case "קבלן":
            switch (lang)
            {
                case "eng":
                    return "contractor";
                case "ENG":
                    return "CONTRACTOR";
                case "heb":
                    return "קבלן";
            }
            break;

        case "supplier":
        case "SUPPLIER":
        case "ספק":
            switch (lang)
            {
                case "eng":
                    return "supplier";
                case "ENG":
                    return "SUPPLIER";
                case "heb":
                    return "ספק";
            }
            break;

        case "customer":
        case "CUSTOMER":
        case "לקוח":
            switch (lang)
            {
                case "eng":
                    return "customer";
                case "ENG":
                    return "CUSTOMER";
                case "heb":
                    return "לקוח";
            }
            break;

        default:
            return "";

    }// end switch (personType)

    return "";

}// end translatePersonType


Can this be refactored to be more concise and maintainable? For reference, this is the database field behind the property:

```
personType SET('CUSTOM

Solution

This kind of switch statements can be refactored using maps/dictionaries. I would do it like this:

Edit: I actually made a couple of mistakes. After adding more unit tests I came up with a hopefully better version.

//V. 2:
public static string TranslatePersonTypeBetterRefactored(string personType, string lang)
{
    var allDicts = new Dictionary>
                        {
                            {
                                "heb", new Dictionary()
                                            {
                                                { "employee", "עובד" },
                                                { "contractor", "קבלן" },
                                                { "supplier", "ספק" },
                                                { "customer", "לקוח" }
                                            }
                            },
                            {
                                "eng", new Dictionary()
                                            {
                                                { "עובד", "employee" },
                                                { "קבלן", "contractor" },
                                                { "ספק", "supplier" },
                                                { "לקוח", "customer" }
                                            }
                            },
                            {
                                "_eng", new Dictionary()
                                            {
                                                { "employee", "employee" },
                                                { "contractor", "contractor" },
                                                { "supplier", "supplier" },
                                                { "customer", "customer" }
                                            }
                            }
                        };

    Dictionary dict;
    string tran;

    if ((allDicts.TryGetValue(lang.ToLower(), out dict) &&
         dict.TryGetValue(personType.ToLower(), out tran)) ||
        (allDicts.TryGetValue(string.Format("_{0}", lang.ToLower()), out dict) &&
         dict.TryGetValue(personType.ToLower(), out tran)))
    {
        var shouldBeUpper = lang.Any(c => char.IsUpper(c));

        return shouldBeUpper ? tran.ToUpper()
                             : tran;
    }

    return string.Empty;
}

//V. 1 (buggy):
public static string TranslatePersonTypeRefactored(string personType, string lang)
{
    var engToUpper = lang == "ENG";
    var engToLower = lang == "eng";

    if (engToUpper && personType.Any(c => char.IsLower(c)))
        return personType.ToUpper();

    if (engToLower && personType.Any(c => char.IsUpper(c)))
        return personType.ToLower();

    var hebrewToEnglishWords = new Dictionary
                        {
                            { "עובד", "employee" },
                            { "קבלן", "contractor" },
                            { "ספק", "supplier" },
                            { "לקוח", "customer" }
                        };

    var hebrewToEngTranslation = hebrewToEnglishWords[personType];

    return engToLower ? hebrewToEngTranslation
                      : hebrewToEngTranslation.ToUpper();
}

Code Snippets

//V. 2:
public static string TranslatePersonTypeBetterRefactored(string personType, string lang)
{
    var allDicts = new Dictionary<string, Dictionary<string, string>>
                        {
                            {
                                "heb", new Dictionary<string, string>()
                                            {
                                                { "employee", "עובד" },
                                                { "contractor", "קבלן" },
                                                { "supplier", "ספק" },
                                                { "customer", "לקוח" }
                                            }
                            },
                            {
                                "eng", new Dictionary<string, string>()
                                            {
                                                { "עובד", "employee" },
                                                { "קבלן", "contractor" },
                                                { "ספק", "supplier" },
                                                { "לקוח", "customer" }
                                            }
                            },
                            {
                                "_eng", new Dictionary<string, string>()
                                            {
                                                { "employee", "employee" },
                                                { "contractor", "contractor" },
                                                { "supplier", "supplier" },
                                                { "customer", "customer" }
                                            }
                            }
                        };

    Dictionary<string, string> dict;
    string tran;

    if ((allDicts.TryGetValue(lang.ToLower(), out dict) &&
         dict.TryGetValue(personType.ToLower(), out tran)) ||
        (allDicts.TryGetValue(string.Format("_{0}", lang.ToLower()), out dict) &&
         dict.TryGetValue(personType.ToLower(), out tran)))
    {
        var shouldBeUpper = lang.Any(c => char.IsUpper(c));

        return shouldBeUpper ? tran.ToUpper()
                             : tran;
    }

    return string.Empty;
}

//V. 1 (buggy):
public static string TranslatePersonTypeRefactored(string personType, string lang)
{
    var engToUpper = lang == "ENG";
    var engToLower = lang == "eng";

    if (engToUpper && personType.Any(c => char.IsLower(c)))
        return personType.ToUpper();

    if (engToLower && personType.Any(c => char.IsUpper(c)))
        return personType.ToLower();

    var hebrewToEnglishWords = new Dictionary<string, string>
                        {
                            { "עובד", "employee" },
                            { "קבלן", "contractor" },
                            { "ספק", "supplier" },
                            { "לקוח", "customer" }
                        };

    var hebrewToEngTra

Context

StackExchange Code Review Q#9934, answer score: 6

Revisions (0)

No revisions yet.