patterncsharpMinor
Refactor embedded switch
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:
Can this be refactored to be more concise and maintainable? For reference, this is the database field behind the property:
```
personType SET('CUSTOM
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 translatePersonTypeCan 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.
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 hebrewToEngTraContext
StackExchange Code Review Q#9934, answer score: 6
Revisions (0)
No revisions yet.