Diese Frage bezieht sich speziell auf C#, aber ich bin auch an Antworten für C++ und Java (oder sogar andere Sprachen, wenn sie etwas Cooles haben) interessiert.
Ich ersetze Switch-Anweisungen durch Polymorphismus in einem "C mit C#-Syntax"-Code, den ich geerbt habe. Ich habe über den besten Weg zur Erstellung dieser Objekte gerätselt. Ich habe zwei Ausweichmethoden, die ich gerne verwende. Ich würde gerne wissen, ob es andere, praktikable Alternativen gibt, die ich in Betracht ziehen sollte, oder einfach nur eine Überprüfung, ob ich das wirklich vernünftig angehe.
Die Techniken, die ich normalerweise verwende:
- Verwenden Sie eine allwissende Methode/Klasse. Diese Klasse füllt entweder eine Datenstruktur auf (höchstwahrscheinlich eine Map) oder konstruiert on-the-fly mit einer Switch-Anweisung.
- Verwenden Sie eine blinde und dumme Klasse, die eine Konfigurationsdatei und Reflexion verwendet, um eine Karte von Instanzen/Delegierten/Fabriken/etc. zu erstellen. Dann verwenden Sie map in einer ähnlichen Weise wie oben.
- ???
Gibt es eine #3, #4... usw., die ich beachten sollte? stark berücksichtigen?
Einige Details... bitte beachten Sie, das ursprüngliche Design ist nicht von mir und meine Zeit ist begrenzt, was das Umschreiben/Refactoring der ganzen Sache angeht.
Vorheriger Pseudocode:
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;
}
Ich habe vor, dies (nach einer umfangreichen Überarbeitung der anderen Objekte) durch etwas Ähnliches zu ersetzen:
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.
}
Die Frage ist, wie die Implementierung von GetParser und GetCommand aussehen sollte.
Das Einfügen einer switch-Anweisung (oder eines Aufrufs einer Fabrik, die aus switch-Anweisungen besteht) scheint nicht sinnvoll zu sein wirklich behebt das Problem. Ich verschiebe den Schalter einfach woanders hin... was vielleicht in Ordnung ist, da er sich nicht mehr in der Mitte meiner primären Logik befindet.