Wie soll man Konstanten in mehreren Sprachen verwalten?

13

Ich habe eine Situation, in der ich eine funktionsgleiche Bibliothek in mehreren Sprachen unterstütze. Es gibt häufig Konstanten, die von diesen gemeinsam genutzt werden müssen (z. B. json-Feldnamenschlüssel oder Fehlercodes).

Die Art und Weise, wie ich dies derzeit tue, ist, dass Code die Konstanten in jeder Sprache definiert.

Das Problem liegt in der Wartung. Wenn ich einen neuen Fehlercode hinzufüge, muss ich ihn in jeder Bibliothek manuell aktualisieren. Während dies für ein paar in Ordnung ist, wird es langweilig, wenn ich 5 sdks zum Aktualisieren sage. Es wäre schön, auch für diese eine einzige Quelle der Wahrheit zu haben.

Ich habe über eine Art Konfigurationsdatei nachgedacht, aber dann muss sie in jedem bereitgestellten Paket enthalten sein, was unseren Build- / Release-Prozess komplexer macht.

Gibt es eine bessere Möglichkeit, die Verwaltung von Konstanten zu verwalten, die von mehreren Sprachen gemeinsam genutzt werden?

Enderland
quelle
Dein Ansatz ist in Ordnung, Enderland. Ich habe versucht, eine bessere Lösung für die Neudefinition zu finden, da häufig mehrere Clients von mir programmierte APIs verwenden und es wirklich keine elegante Lösung gibt. Die Neudefinition von Konstanten ist immer noch am einfachsten.
Andy
5
@DavidPacker nein nein nein du sollst eine wirklich elegante Lösung für mich haben. Sag mir nicht, das ist das Beste, was es gibt! :-)
Enderland
1
Ich habe meine Wahl hinterfragt, dann aber festgestellt, dass Konstanten konstant sein sollen. Sie sind vorhersehbar, weil sie konstant sind. Durch das Speichern in einem JSON-Format oder einem anderen allgemein analysierbaren Format sind sie keine wirklichen Konstanten mehr. Ein typisches Beispiel in meinem Arbeitsprozess ist ein Benachrichtigungsobjekt, das ein typeAttribut zur Strukturidentifikation enthält, wenn es über die Leitung übertragen wird. Auf diese Weise definieren die mobilen Clients nur Konstanten (Typen), die sie zur Zeit verstehen, und ignorieren unbekannte Typen. Die dynamische Definition würde viele Probleme verursachen.
Andy
Sie benötigen eine Tabelle mit Tabellen, die Konstantenzeilen aus Sprachtabellen zugeordnet sind.
Johnny

Antworten:

10

Obwohl ich denke, dass Ihr derzeitiger Ansatz wahrscheinlich der einfachste und direkteste ist, sind hier einige alternative Ideen:

  • Extrahieren Sie Ihre Konstanten (und möglicherweise Modelle) in ein anderes Paket, das in alle Ihre Sprachen übersetzt wird. Möglicherweise können Sie die gesamte Bibliothek übergreifend kompilieren, dies kann jedoch mit erheblichen Problemen verbunden sein. Nur das Kreuzkompilieren von Konstanten sollte so einfach sein, dass es nicht so viele Probleme gibt. Sie können Ihr Konstantenpaket veröffentlichen und es in Ihren sprachspezifischen Bibliotheken verwenden. Haxe kann es wahrscheinlich tun. Dieser Ansatz ist gut, da Sie immer noch die Kompilierungszeit überprüfen müssen (für kompilierte Sprachen).
  • Speichern Sie die Konfiguration in einem zentralen Dienst. So verfügen beispielsweise Soap-Webdienste über die Web Service Description Language (WSDL) und REST-Dienste über die Web Application Description Language (WADL), die die Vorgänge und Nachrichten des Dienstes beschreibt. Es gibt auch allgemeine zentrale Konfigurationsdienste wie Spring Cloud Config
  • Konfigurationsdatei. Ich weiß, dass Sie es bereits vorgeschlagen haben, aber ich denke nicht, dass es Ihren Build- / Release-Prozess sehr komplizieren muss. Legen Sie Ihre Konfigurationsdatei in einem separaten Build-Projekt ab (wo Sie sie versionieren können). Veröffentlichen Sie das Projekt in Ihren sprachspezifischen Paket-Repositorys (Maven, Nuget, NPM usw.). In Ihren sprachspezifischen Bibliotheken können Sie sich dann auf das Paket verlassen. Dies sollte nicht komplexer sein, als ein zusätzliches Projekt in Ihrer Build-Pipeline zu haben.
  • Wie RubberDuck vorschlug, ist die Codegenerierung eine gute Alternative zum Cross-Compilieren. Sie können konstante Definitionen für jede Sprache unter Verwendung einer gemeinsamen Konfiguration erstellen.
Samuel
quelle
5
Die @RubberDuck-Codegenerierung klingt interessant (insbesondere für einen meiner tangentialen Anwendungsfälle, in denen sowieso bereits ein Codegenerator verwendet wird).
Enderland
3

Gute Frage! Ich habe genau das gleiche Problem. Meine Konstanten sind im Wesentlichen: Welche Sprachen werden in meinen Anwendungen unterstützt? Und zusätzliche Informationen zu diesen Sprachen, da sie sich auf die Funktionalität in der App beziehen.

Leider ist das Beste, was ich (wie Sie) gefunden habe, einfach Konstanten für jede Sprache neu zu definieren, wie Sie es gerade tun (ich weiß, das wollten Sie unbedingt hören ).

Offensichtlich fühlt es sich falsch an weil es das Gegenteil von DRY ( WET ?? ) ist. Konstanten sollten sich jedoch so selten ändern, dass mich die fünf bis zehn Minuten, in denen sie für jede Sprache neu definiert wurden, nicht wirklich stören. Letztendlich können kleine Probleme mit „eleganten“ Lösungen wie der gemeinsamen Konfiguration oder der Codegenerierung Stunden oder Tage in Anspruch nehmen. Was ist also wirklich gewonnen? Zusätzliche Komplexität mit dem Risiko, dass etwas schief geht und zusätzliche Anstrengungen erforderlich sind, ist etwas, mit dem ich mich nicht befassen möchte.

Wenn Ihre Anwendung über so viele Konstanten verfügt, dass die Neudefinition dieser Konstanten pro Sprache beim Hinzufügen oder Ändern viel Zeit in Anspruch nimmt, ist möglicherweise nur ein wichtigerer Codegeruch zu behandeln, und an diesem Punkt möchten Sie möglicherweise die Konstante aktivieren zu etwas Komplexerem.

Kurz gesagt, es war meine beste Lösung, sie für jede Sprache neu zu definieren, und ich habe noch nichts TROCKENERES gefunden, das keinen größeren Risikofaktor hätte, als ich behandeln möchte.

Eine Sache, die Sie auf jeden Fall tun sollten, ist sicherzustellen, dass Ihre Konstanten in einer verallgemeinerten (und sprachunabhängigen) Weise gut dokumentiert sind dieses Dokument). Stellen Sie außerdem sicher, dass Mechanismen vorhanden sind, um die Definitionen synchron zu halten. Das ist ein ungefähr so ​​großes Problem mit dem Duplizierungsansatz wie Sie, abgesehen von einer kleinen psychischen Belastung durch absichtliche Code-Duplizierung. Aber am Ende sollten Ihre ständigen Änderungen sehr bewusst und selten sein , so dass Synchronitätsprobleme im Wesentlichen gleich Null sein sollten.


Ich sollte auch erwähnen, dass ich im Laufe der Jahre mehrsprachige Ports verschiedener Bibliotheken gesehen habe (zu müde, um sich daran zu erinnern, was sie im Moment sind), die von derselben Gruppe geschrieben wurden, deren Konstanten immer in den Sprachen selbst definiert sind. Keine gemeinsame Konfiguration, keine Codegenerierung (mit Ausnahme der Google API-Clientbibliotheken ... Google verfügt jedoch über die Ressourcen, um sich eine solche Komplexität zu leisten). Ich denke, wir haben eine Ziegelmauer getroffen. Vielleicht kommt irgendwann jemand mit einer Bibliothek, um dieses Problem zu lösen;)

Chris Cirefice
quelle
0

Hoffentlich ist der Kern Ihrer Bibliothek in einer Sprache geschrieben, und die anderen Bibliotheken verwenden FFI ( https://en.wikipedia.org/wiki/Foreign_function_interface ), um die Kernbibliothek aufzurufen. Dies würde Ihnen den zentralen Ort geben, um eine API bereitzustellen, von der aus Sie die Konstanten und Definitionen veröffentlichen können. Auf diese Weise ist alles in der Bibliothek in sich geschlossen. Ich erwähne dies nur, da es nicht in Samuels Antwort enthalten zu sein scheint.

Ich denke, es hängt wirklich davon ab, wie leistungsfähig Ihre Benutzerbasis ist. Sind die fähig genug, um mit dem Weitergeben einer anderen Konfigurationsdatei fertig zu werden? Sind sie in der Lage, einen neuen Dienst einzurichten? Für die große Mehrheit der von mir unterstützten Benutzer möchte ich, dass alles in sich geschlossen ist - auf diese Weise müssen die Benutzer nicht darüber nachdenken.

Robert Baron
quelle
1
Hopefully, the core of you library is written in one language, and the other libraries use FFI Leider haben wir Bibliotheken sowohl für einen Web-Client- als auch für einen Server-Code (in mehreren Sprachen), so dass es nicht trivial wäre, diese abzurufen (und wahrscheinlich eine Sicherheitslücke, wenn wir in der Web-App damit anfangen könnten).
Enderland
Ich würde vorschlagen, dass Sie Ihre Sicherheit verbessern, da ich meinen Benutzern niemals genug vertrauen würde, um Konfigurationsdateien geheim zu halten.
Robert Baron
Wie implementieren Sie Webanwendungen, die mit Fehlercodes umgehen? Oder json Feldnamen? Ich bin verwirrt von dem, was ich Ihrer Meinung nach tue, da es sich um ein Sicherheitsproblem handelt. Das Ausführen von willkürlichem Code auf dem Computer meines Clients ist absolut sicherheitsrelevant. Das Analysieren von JSON von einem Server scheint nur dann möglich zu sein, wenn mir etwas fehlt.
Enderland
Ich habe in Unternehmen gearbeitet, deren Basis für die Sicherheit Zufallszahlengeneratoren im DOS-Stil und als Konstanten gespeicherte Startwerte waren. Diese waren in der Regel sehr schnell behoben, nachdem sie darauf hingewiesen wurden. Wenn Sie jedoch den Startwert in die Welt setzen, geben Sie den Schlüssel zum Königreich preis. Da Ihre Software hauptsächlich webbasiert zu sein scheint, lassen Sie die Konfiguration in einem JSON-Objekt und alle Sprachen gleich freigegebene Datei.
Robert Baron
JSON-Feldnamen müssen und müssen wahrscheinlich nicht konstant sein. Wie hoch wären die Chancen, dass sich diese Feldnamen ändern müssten, aber Sie ändern nicht den Namen der Konstanten selbst? Es ist wahrscheinlich wahrscheinlicher, dass Sie davon profitieren, Code für den Zugriff auf Einträge zu generieren oder eine Ausdruckssprache wie ObjectPath zu verwenden.
Lie Ryan