2009-06-02 16 views
3

ich habe:Wie würden Sie eine Konsolenanwendung aus einer vorhandenen objektorientierten API erstellen?

  • bestehende objektorientierte nativen Code API (nicht GUI)
  • GUI-Anwendung, die mit dieser API arbeitet

Das Ziel: eine zusätzliche Konsolenanwendung zu erstellen, die Benutzer können Führen Sie eine Reihe von Arbeitsabläufen durch (ähnlich wie in der obigen GUI-App), indem Sie Befehle eingeben. Diese App sollte "stateful" sein - verfügbare Befehle und deren Ergebnisse hängen von den zuvor ausgegebenen Befehlen ab.

Das Problem: Ich möchte nicht "das Rad neu zu erfinden". Gibt es Muster für den Aufbau der App und die Definition des "Vokabulars"? Momentan scheint es mir die beste Option zu sein, einen Satz von Helfern und Befehlsparsern "von Grund auf" zu schreiben.

P.S. Wenn meine API in .Net wäre, würde ich in die PowerShell-Richtung schauen, aber die API ist groß und das Einschließen in .Net ist sehr zeitaufwendig.

Antwort

1

Um in der Befehlszeile zu beginnen, erfinden Sie das Rad zunächst nicht neu. Es gibt viele Möglichkeiten, Befehle zu parsen.

In Java gibt es Commons CLI, die Ihnen alles bietet, was Sie brauchen. Es gibt auch eine .NET CLI port.

InfiniteRed hat a good writeup davon, wie man das in Ruby macht.

Soweit die Umsetzung geht, haben Sie die richtige Idee. Aber erfinden Sie das Rad hier auch nicht neu. Verkapseln Sie die Arbeit in Command Objekte und schauen Sie sich das Pattern Chain of Responsibility an. Commons Chain funktioniert gut. Es gibt auch eine .NET Chain port.

Wenn die Verwendung dieser Frameworks keine Option ist, sehen Sie sich an, wie sie implementiert sind. Auch wenn Sie ein Problem haben, mit einigen dieser Optionen zu interopieren, ist Ruby wirklich ein schönes Schweizer-Armee-Messer für diese Art von Sache. Es ist relativ portabel und der Code kann wirklich sauber und leicht zu pflegen sein.

UPDATE: JCommander sieht auch interessant aus.

+0

Chain of Responsibility ist ziemlich nah zu Hause, danke! –

+0

Ich denke, das ist wahrscheinlich alles, was Sie brauchen würden. Schieben Sie einfach alle benötigten Zustände in den Ausführungskontext der Kette. – cwash

1

Haben Sie COM-Schnittstellen? PowerShell kann COM, WMI oder .NET nahtlos scriptfähig machen; Sie könnten sogar p/invoke Calls mit reinem Skript ausführen; viel weniger zeitaufwändig für den Prototypen. Sobald Sie das Design erstarrt haben, können Sie optional später als native Cmdlets für Geschwindigkeit umbrechen.

-Oisin

+0

Es scheint, als Staat für die Aufrechterhaltung der ‚verfügbaren Befehle auf API-Zustandsänderung basiert‘ Anwendungsfall nicht selbst verleihen in einem Zustand-Licht-Umgebung wie eine Login-Shell Betrieb ... ist mein Eindruck von Fähigkeit des Powershell für Cmdlets zum Interagieren mit einem Statusspeicher falsch? –

+0

Meine Gedanken genau. Ich würde stark in Betracht ziehen, ein com-Objekt aus Ihrer API zu erstellen. Es wird wahrscheinlich auch der schnellere Ansatz sein. – skamradt

+0

@Tetsujin Powershell hat das Konzept der dynamischen Parameter, die bedingt auf vorhandenen Befehlen zur Verfügung gestellt werden, die vollständig vom Status des Backup-Speichers abhängen - normalerweise als Provider gekapselt. Der Schalter "-Wait" wird beispielsweise vom Dateisystemanbieter dem Cmdlet "Get-Content" hinzugefügt, das vom aktuellen Pfad zu diesem Anbieter und/oder seinem internen Status abhängig sein kann. – x0n

1

Wenn Sie .net am Ende tun mit, vielleicht könnten Sie einen Blick @ die Bibliothek Mono.Options nehmen: http://tirania.org/blog/archive/2008/Oct-14.html

„Mono.Options ist eine schöne Befehl Linie Parsing Es ist klein, prägnant, eine Freude zu bedienen, einfach und leistungsstark, alles in einem. "

+0

Auch wenn nicht. NET, gut als Muster! –

3

Das von Ihnen beschriebene Anwendungsmuster klingt wie eine Read-Eval-Print-Schleife (REPL), der übliche Interaktionsmodus für interpretierte Sprachen.

Tatsächlich scheinen Sie eine Befehlssprache und einen Interpreter zu beschreiben. Daher würde ich vorschlagen, diese Domäne nach Mustern zu untersuchen, die mit Ihrer bestehenden Bindung für die API übereinstimmen.

0

Ich stimme stark mit der Antwort von xOn überein, aber um den Zustand zwischen den Anrufen beizubehalten, mache es einfach zu einem einzigen Instanz-com-Objekt, schreibe dann eine "Login" -Funktion zum Aufrufen von AddRef und eine "Abmelde" -Funktion zum Aufrufen von Release. Auf diese Weise bleibt das Objekt zwischen den Anrufen hängen. Das einzige Risiko besteht darin, dass mehrere Runs auf derselben Box mit mehreren Logins durchgeführt werden ... also sollten Sie dafür eine Falle stellen.

Je nach dem Status, den Sie benötigen, wenn es nicht viel ist und problemlos auf eine Festplattendatei oder Datenbank gestreamt werden kann, würde sich ein Multiinstanz-com-Objekt besser verhalten und würde keine addref- oder release-Aufrufe erfordern.

1

Wickeln Sie Ihre API mit automatischen Tools wie SIP oder SWIG, importieren sie als Python-Modul in eine ipython Sitzung, tun Dinge mit Ihren Objekten aus der Kommandozeile. Job erledigt.

Wenn dies nicht gelingt, wird es sein, weil entweder:

  • Ihre Objekte/API nicht geeignet für die automatische Verpackung (aber dabei, sie in einen wickelbar Zustand des Erhaltens der Regel bedeutet, sie zu verbessern).
  • Python ist nicht wirklich das, was Sie für eine Befehlszeile im Sinn hatten (sogar mit den ipython-Erweiterungen).
Verwandte Themen