Erstellen eine Interaktive Eingabeaufforderung in C++
Ich habe ein Programm, das Lesen sollte-Befehle aus der Konsole und je nach Befehl führen Sie eine von mehreren Aktionen. Hier ist was ich habe, so weit:
void ConwayView::listening_commands() {
string command;
do {
cin >> command;
if ("tick" == command)
{
//to do
}
else if ("start" == command)
{
//to do for start
}
...
} while (EXIT != command);
}
Mit einem switch
an die Stelle der if
Aussagen hilft ein wenig, wenn es eine große Menge von Befehlen. Welche Muster haben Sie vorschlagen, um die interaktive Kommandozeile?
- command-pattern?
- Wie vorgeschlagen. Durch die Art und Weise haben Sie, um eine Liste aller verfügbaren Befehle irgendwo.
- Es ist nicht zuverlässig zu haben ein switch-case bedeutet, dass string-Vergleiche. String vergleicht getan werden sollte mit strcmp oder ähnliches
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn die Anzahl der Befehl ist klein und mögliche Parameter sind wirklich nur wenige, man könnte immer mit switch case !
Wenn die Anzahl der Befehle erhöht, sollten das command design pattern (das ist IMHO eine Art von Strategie-Muster verkleidet: cf Mit einer Strategie, - Muster und ein command-Muster für die Unterschiede zwischen Kommando-und Strategie-Muster).
Wenn die meisten Ihrer Befehle sind alle teilen ein Teil das gleiche Verhalten, vergessen Sie nicht das template Methode-Muster.
Wenn die Komplexität für die Erstellung Ihrer command-Objekte erhöht ( d.h. es ist die Komplexität bei der Decodierung/das Verständnis der input von der command line), Sie sollten beginnen, der interpreter design pattern
Wenn bei der Gestaltung mit Hilfe der interpreter-Muster, die Sie passieren, um zu sehen, einige Komplexität ( wenn der Dolmetscher muss zu viel Arbeit, Sie sehen, syntax und so weiter ), dann sollten Sie wahrscheinlich Blick auf DSL, domain specific language, und gestalten Sie Ihre eigene Sprache, die passt (und nur dann passt Sie eigenen Eingängen.
Gibt es mehrere Möglichkeiten, um dieses Problem zu lösen, und es ist fraglich, was die "richtige" Lösung ist. Wenn ich waren zu lösen, um es für meine eigene Arbeit, ich würde eine Tabelle erstellen einer benutzerdefinierten Struktur. So etwas wie:
Dann meine Verarbeitung Schleife würde Fuß durch jedes element der Tabelle, auf der Suche nach dem richtigen match, etwa:
Nicht wirklich ein Muster, aber oft ein guter Ansatz:
Den
if
-else
Leiter ist in Ordnung.Es kann im Prinzip ersetzt werden durch eine
map<string, Function>
, aber das erhält Sie nichts für diesen konkreten Fall (es ist zusätzliche Komplexität für die keine besonderen gewinnen, selbst bei einer hohen Anzahl von Befehlen).Als ich schrieb das ich anfangs vergessen zu erwähnen aber:
Wenn Sie nicht, dann der
if
-else
Leiter kann sehr chaotisch... Diemap
Lösung erfordert separate Funktionen, und kann daher angezeigt sein, ein wenig mehr sauber als ein alles-direkt-hierif
-else
Leiter. Aber es ist wirklich der verschiedene Funktionen, die dann ein gewisses Maß an Klarheit, während diemap
trübt ein wenig (das hinzufügen zusätzlicher Arbeit bei der Aufrechterhaltung der Karte, und eine zusätzliche Dereferenzierungsebene zu bewältigen).Auf der anderen Seite, da "lese-Befehle von der Konsole aus" zeigt an interaktive Eingabe, mit der ein Benutzer in das Bild, Sie wollen nicht Lesen, zwei oder mehrere Befehle aus der gleichen Zeile der Eingabe. Denn das würde Sie versauen die Aufforderung, und scheinen ziemlich verwirrend für den Benutzer. Also anstatt zu Lesen, ein "Wort" von input-zu einer Zeit
>>
verwendenstd::getline
zu einem Lesen Sie die vollständige Zeile zu einem Zeitpunkt.verwenden Sie die neuen und verbesserten Weg zu preform eine Reihe von Befehlen wird:
int happy_time = 5;
int a = happy_time;
int muddy_dirt = 1;
int b = muddy_dirt;
int c = happy_time * muddy_dirt //wirklich chaotisch stuff
das ist wahrscheinlich die am wenigsten komplizierte Art und Weise, es zu tun....
Müssen Sie die Datenbank wie access, wenn Ihr Befehl ist groß.