Bei meinen Bemühungen, ein Programm zur Konjugation von Verben (algorithmisch, nicht über einen Datensatz) für Französisch zu schreiben, bin ich auf ein kleines Problem gestoßen.
Der Algorithmus zur Konjugation der Verben ist für die etwa 17 Fälle von Verben eigentlich recht einfach und wird für jeden Fall nach einem bestimmten Muster ausgeführt. Daher sind die Konjugationssuffixe für diese 17 Klassen statisch und werden sich (sehr wahrscheinlich) in Kürze nicht mehr ändern. Zum Beispiel:
// Verbs #1 : (model: "chanter")
terminations = {
ind_imp: ["ais", "ais", "ait", "ions", "iez", "aient"],
ind_pre: ["e", "es", "e", "ons", "ez", "ent"],
ind_fut: ["erai", "eras", "era", "erons", "erez", "eront"],
participle: ["é", "ant"]
};
Dies sind Beugungssuffixe für die häufigste Verbklasse in Französisch.
Es gibt andere Klassen von Verben (Unregelmäßigkeiten), deren Konjugationen höchstwahrscheinlich auch für die nächsten ein oder zwei Jahrhunderte statisch bleiben werden. Da sie unregelmäßig sind, müssen ihre vollständigen Konjugationen statisch eingeschlossen werden, da sie nicht zuverlässig aus einem Muster konjugiert werden können (es gibt auch nur [nach meiner Zählung] 32 Unregelmäßigkeiten). Zum Beispiel:
// "être":
forms = {
ind_imp: ["étais", "étais", "était", "étions", "étiez", "étaient"],
ind_pre: ["suis", "es", "est", "sommes", "êtes", "sont"],
ind_fut: ["serai", "seras", "sera", "serons", "serez", "seront"],
participle: ["été", "étant"]
};
Ich könnte das alles in XML oder sogar JSON einfügen und es deserialisieren, wenn es verwendet werden muss, aber gibt es einen Punkt? Diese Saiten sind Teil der natürlichen Sprache, die sich zwar ändert, jedoch nur langsam.
Meine Sorge ist , dass durch die Dinge , die „richtige“ Art und Weise und Deserialisieren einige Datenquelle zu machen, ich habe nicht nur das Problem kompliziert , die nicht brauchen kompliziert zu sein, aber ich habe auch ganz zurück Abwege auf das gesamte Ziel der algorithmischer Ansatz: nicht eine Datenquelle verwenden! In C # könnte ich einfach eine Klasse unter namespace Verb.Conjugation
(z. B. class Irregular
) erstellen , um diese Zeichenfolgen in einem Aufzählungstyp oder etwas anderem unterzubringen, anstatt sie in XML einzufügen und eine zu erstellen class IrregularVerbDeserializer
.
Also die Frage: ist es zu hart Codefolgen angemessen , dass es sehr unwahrscheinlich , dass Änderung während der Lebensdauer einer Anwendung? Natürlich kann ich nicht 100% ig garantieren, dass sie sich nicht ändern, aber das Risiko gegenüber den Kosten ist in meinen Augen fast trivial - Hardcoding ist hier die bessere Idee.
Bearbeiten : In dem vorgeschlagenen Duplikat wird gefragt, wie eine große Anzahl statischer Zeichenfolgen gespeichert werden soll. Meine Frage lautet jedoch, wann ich diese statischen Zeichenfolgen fest codieren soll .
Antworten:
Es scheint mir, dass Sie Ihre eigene Frage beantwortet haben.
Eine der größten Herausforderungen besteht darin, die Dinge, die sich wahrscheinlich ändern, von den Dingen zu trennen, die sich nicht ändern werden. Manche Leute sind verrückt und geben absolut alles, was sie können, in eine Konfigurationsdatei. Andere gehen zum anderen Extrem und erfordern eine Neukompilierung, um selbst die offensichtlichsten Änderungen zu erzielen.
Ich würde den einfachsten Implementierungsansatz wählen, bis ich einen überzeugenden Grund gefunden habe, es komplizierter zu machen.
quelle
French.Verb.Irregular.Etre
die Daten aus meiner Frage enthalten würde. Ich denke, es funktioniert in Ordnung;)if (num == 0xFFD8)
). Dieses Beispiel sollteif (num == JPEG_MAGIC_NUMBER)
aus Gründen der Lesbarkeit in fast allen Fällen so aussehen . Ich weise nur darauf hin, weil das Wort "Hardcoding" aufgrund dieser alternativen Bedeutung des Wortes häufig Haare im Nacken der Menschen aufwirft (wie meines).JPEG_START_OF_IMAGE_MARKER
?Sie argumentieren im falschen Rahmen.
Sie haben nicht nur einzelne Verben fest codiert. Sie haben die Sprache und ihre Regeln fest programmiert . Dies bedeutet wiederum, dass Ihre Anwendung nicht für eine andere Sprache verwendet und nicht mit anderen Regeln erweitert werden kann.
Wenn Sie dies beabsichtigen (dh nur für Französisch verwenden), ist dies aufgrund von YAGNI der richtige Ansatz. Aber Sie geben selbst zu, dass Sie es später auch für andere Sprachen verwenden möchten, was bedeutet, dass Sie sehr bald den gesamten fest codierten Teil in die Konfigurationsdateien verschieben müssen. Die verbleibende Frage ist:
Werden Sie die App in naher Zukunft mit einer Sicherheit von nahezu 100% auf andere Sprachen ausweiten? In diesem Fall hätten Sie Dinge in JSON- oder XML-Dateien (für Wörter, Wortteile usw.) und dynamische Sprachen (für Regeln) exportieren müssen, anstatt sich zu zwingen, den größten Teil Ihrer App neu zu schreiben.
Oder besteht nur eine geringe Wahrscheinlichkeit, dass die App in Zukunft erweitert wird. In diesem Fall schreibt YAGNI vor, dass der einfachste Ansatz (der, den Sie gerade verwenden) der bessere ist.
Nehmen Sie zur Veranschaulichung die Rechtschreibprüfung von Microsoft Word. Wie viele Dinge sind Ihrer Meinung nach fest codiert?
Wenn Sie ein Textverarbeitungsprogramm entwickeln, könnten Sie durch eine einfache Rechtschreibprüfung mit fest einprogrammierten Regeln und sogar fest einprogrammierter Worten beginnen:
if word == "musik": suggestSpelling("music");
. Schnell werden Sie anfangen, Wörter zu bewegen, und sich dann außerhalb Ihres Codes anordnen. Andernfalls:Wie Sie sich selbst hervorgehoben haben:
Sobald Sie die Regeln für eine Sprache fest programmieren, benötigt jede andere Sprache immer mehr Code, insbesondere angesichts der Komplexität natürlicher Sprachen.
Ein weiteres Thema ist, wie Sie diese unterschiedlichen Regeln ausdrücken, wenn nicht durch Code. Letztlich können Sie feststellen , dass eine Programmiersprache ist das beste Werkzeug dafür. In diesem Fall können dynamische Sprachen eine gute Alternative sein , wenn Sie die Engine erweitern müssen, ohne sie neu zu kompilieren .
quelle
LanguageProcessor
Klasse mit mehreren Unterklassen haben. (Eigentlich ist die "Konfigurationsdatei" eine Klasse)Zeichenfolgen sollten in eine Konfigurationsdatei oder Datenbank extrahiert werden, wenn sich die Werte unabhängig von der Programmlogik ändern könnten .
Zum Beispiel:
Extrahieren von UI-Texten in Ressourcendateien. Dies ermöglicht es einem Nicht-Programmierer, die Texte zu bearbeiten und Korrektur zu lesen, und es ermöglicht das Hinzufügen neuer Sprachen durch Hinzufügen neuer lokalisierter Ressourcendateien.
Extrahieren von Verbindungszeichenfolgen, URLs zu externen Diensten usw. in Konfigurationsdateien. Auf diese Weise können Sie verschiedene Konfigurationen in verschiedenen Umgebungen verwenden und die Konfigurationen im laufenden Betrieb ändern, da sie möglicherweise aus Gründen außerhalb Ihrer Anwendung geändert werden müssen.
Eine Rechtschreibprüfung, die ein Wörterbuch mit zu überprüfenden Wörtern enthält. Sie können neue Wörter und Sprachen hinzufügen, ohne die Programmlogik zu ändern.
Das Extrahieren in die Konfiguration ist jedoch mit einem hohen Aufwand verbunden und nicht immer sinnvoll.
Zeichenfolgen können fest codiert sein, wenn sich die tatsächliche Zeichenfolge nicht ändern kann, ohne die Programmlogik zu ändern.
Beispiele:
In Ihrem Fall denke ich, dass es klar ist, dass die Wörter ein integraler Bestandteil der Programmlogik sind (da Sie einen Konjugator mit bestimmten Regeln für bestimmte Wörter erstellen) und das Extrahieren dieser Wörter in eine externe Datei keinen Wert hat.
Wenn Sie eine neue Sprache hinzufügen, müssen Sie trotzdem neuen Code hinzufügen, da jede Sprache eine spezifische Konjugationslogik hat.
Einige haben vorgeschlagen , dass Sie irgendeine Art von hinzufügen könnte Regel - Engine , die Sie Konjugationsregeln für beliebige Sprachen angeben können, so neue Sprachen rein durch Konfiguration hinzugefügt werden könnten. Überlegen Sie genau, bevor Sie diesen Weg gehen, denn die menschlichen Sprachen sind wunderbar seltsam. Sie benötigen daher eine sehr ausdrucksstarke Regel-Engine. Sie würden im Grunde genommen eine neue Programmiersprache (eine Konjugations-DSL) erfinden, um zweifelhaften Nutzen daraus zu ziehen. Sie haben aber bereits eine Programmiersprache zur Verfügung, die alles kann, was Sie brauchen. Auf jeden Fall YAGNI.
quelle
Ich stimme der Antwort von Dan Pichelman zu 100% zu, möchte aber eines hinzufügen. Die Frage, die Sie sich hier stellen sollten, lautet: "Wer wird die Wortliste pflegen / erweitern / korrigieren?". Wenn es immer die Person ist, die auch die Regeln einer bestimmten Sprache einhält (der bestimmte Entwickler, denke ich, Sie), dann macht es keinen Sinn, eine externe Konfigurationsdatei zu verwenden, wenn dies die Dinge komplexer macht - Sie werden keinen Nutzen daraus ziehen diese. Aus dieser Sicht wird es sinnvoll macht solche Wortlisten selbst zu codieren , wenn Sie haben sie von Zeit zu Zeit zu ändern, solange es ausreichend ist , um eine neue Liste als Teil einer neuen Version zu liefern.
(Wenn die Wahrscheinlichkeit gering ist, dass jemand anderes die Liste in Zukunft verwalten kann, oder wenn Sie die Wortlisten ändern müssen, ohne eine neue Version Ihrer Anwendung bereitzustellen, verwenden Sie eine separate Datei.)
quelle
Auch wenn die Hardcodierung hier in Ordnung zu sein scheint und besser als das dynamische Laden von Konfigurationsdateien, würde ich dennoch empfehlen, dass Sie Ihre Daten (das Wörterbuch der Verben) strikt vom Algorithmus trennen . Sie können diese während des Erstellungsprozesses direkt in Ihre Anwendung kompilieren.
Dies erspart Ihnen viel Aufsehen bei der Pflege der Liste. In Ihrem VCS können Sie leicht feststellen, ob ein Commit den Algorithmus geändert oder nur einen Konjugationsfehler behoben hat. Außerdem muss die Liste möglicherweise in Zukunft für Fälle angehängt werden, die Sie nicht berücksichtigt haben. Insbesondere die Anzahl der 32 unregelmäßigen Verben, die Sie gezählt haben, scheint nicht genau zu sein. Während diese scheinen, die allgemein verwendeten abzudecken, fand ich Hinweise auf 133 oder sogar 350 von ihnen.
quelle
Der wichtige Teil ist die Trennung von Bedenken. Wie Sie das erreichen, ist weniger relevant. dh Java ist in Ordnung.
Unabhängig davon, wie die Regeln ausgedrückt werden, müssen Sie eine Änderungssprache für eine Regel hinzufügen: Wie viele Codes und Dateien müssen Sie bearbeiten?
Im Idealfall sollte das Hinzufügen einer neuen Sprache entweder durch Hinzufügen einer 'english.xml'-Datei oder eines neuen' EnglishRules implementiert ILanguageRules'-Objekts möglich sein. Eine Textdatei (JSON / XML) bietet Ihnen einen Vorteil, wenn Sie sie außerhalb Ihres Build-Lebenszyklus ändern möchten, jedoch eine komplexe Grammatik und Analyse benötigen und das Debuggen schwieriger ist. Mit einer Codedatei (Java) können Sie komplexe Regeln auf einfachere Weise ausdrücken, müssen jedoch neu erstellt werden.
Ich würde mit einer einfachen Java-API hinter einer sauberen sprachunabhängigen Oberfläche beginnen - wie Sie das in beiden Fällen brauchen. Sie können später jederzeit eine Implementierung dieser Schnittstelle hinzufügen, die durch eine XML-Datei unterstützt wird, aber ich sehe keine Notwendigkeit, dieses Problem sofort (oder überhaupt) anzugehen.
quelle