Этот вопрос конкретно касается C #, но мне также интересны ответы на C ++ и Java (или даже на другие языки, если у них есть что-то классное).
Я заменяю операторы switch полиморфизмом в коде "C используя синтаксис C #", который я унаследовал. Я ломал голову над лучшим способом создания этих объектов. У меня есть два запасных метода, которые я использую. Я хотел бы знать, есть ли другие, жизнеспособные альтернативы, которые я должен рассмотреть, или просто проверка здравомыслия, что я на самом деле иду об этом разумным способом.
Методы, которые я обычно использую:
- Используйте всезнающий метод / класс. Этот класс будет либо заполнять структуру данных (скорее всего, Map), либо создавать на лету с помощью оператора switch.
- Используйте слепой и тупой класс, который использует конфигурационный файл и отражение для создания карты экземпляров / делегатов / фабрик / и т. Д. Затем используйте карту способом, аналогичным описанному выше.
- ???
Есть ли # 3, # 4 ... и т. Д., Которые я должен решительно рассмотреть?
Некоторые подробности ... пожалуйста, обратите внимание, оригинальный дизайн не мой, и мое время ограничено настолько, чтобы переписать / рефакторинг всей вещи.
Предыдущий псевдокод:
public string[] HandleMessage(object input) {
object parser = null;
string command = null;
if(input is XmlMessage) {
parser = new XmlMessageParser();
((XmlMessageParser)parser).setInput(input);
command = ((XmlMessageParser)parser).getCommand();
} else if(input is NameValuePairMessage) {
parser = new NameValuePairMessageParser();
((NameValuePairMessageParser)parser).setInput(input);
command = ((XmlMessageParser)parser).getCommand();
} else if(...) {
//blah blah blah
}
string[] result = new string[3];
switch(command) {
case "Add":
result = Utility.AddData(parser);
break;
case "Modify":
result = Utility.ModifyData(parser);
break;
case ... //blah blah
break;
}
return result;
}
То, что я планирую заменить на (после большого рефакторинга других объектов), выглядит примерно так:
public ResultStruct HandleMessage(IParserInput input) {
IParser parser = this.GetParser(input.Type); //either Type or a property
Map<string,string> parameters = parser.Parse(input);
ICommand command = this.GetCommand(parameters); //in future, may need multiple params
return command.Execute(parameters); //to figure out which object to return.
}
Вопрос в том, какой должна быть реализация GetParser и GetCommand?
Размещение оператора switch (или вызова фабрики, состоящей из операторов switch) не похоже на то, что действительно решает проблему. Я просто перемещаю переключатель в другое место ... что может быть хорошо, так как его больше нет в середине моей основной логики.