Donc, dans mes efforts pour écrire un programme pour conjuguer des verbes (algorithmiquement, pas via un ensemble de données) pour le français, j'ai rencontré un léger problème.
L'algorithme pour conjuguer les verbes est en fait assez simple pour les 17 cas de verbes environ, et fonctionne sur un modèle particulier pour chaque cas; ainsi, les suffixes de conjugaison pour ces 17 classes sont statiques et ne changeront (très probablement) pas de sitôt. Par exemple:
// 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"]
};
Ce sont des suffixes flexionnels pour la classe de verbe la plus courante en français.
Il existe d'autres classes de verbes (irréguliers), dont les conjugaisons resteront également très probablement statiques pour le prochain siècle ou deux. Puisqu'ils sont irréguliers, leurs conjugaisons complètes doivent être incluses statiquement, car elles ne peuvent pas être conjuguées de manière fiable à partir d'un modèle (il n'y a aussi que [selon mon compte] 32 irrégularités). Par exemple:
// "ê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"]
};
Je pourrais mettre tout cela en XML ou même en JSON et le désérialiser quand il doit être utilisé, mais y a-t-il un point? Ces chaînes font partie du langage naturel, qui change, mais à un rythme lent.
Ma préoccupation est qu'en faisant les choses de la "bonne" manière et en désérialisant une source de données, j'ai non seulement compliqué le problème qui n'est pas besoin d'être compliqué, mais j'ai aussi complètement back-tracked sur l'ensemble de l'objectif de l'approche algorithmique: pour ne pas utiliser une source de données! En C #, je pouvais simplement créer une classe sous namespace Verb.Conjugation
(par exemple. class Irregular
) pour héberger ces chaînes dans un type énuméré ou quelque chose, au lieu de les bourrer en XML et de créer un class IrregularVerbDeserializer
.
Donc la question: est-elle appropriée pour les chaînes de code dur qui sont très peu susceptibles de changer pendant la durée de vie d'une application ? Bien sûr, je ne peux pas garantir 100% qu'ils ne changeront pas, mais le risque par rapport au coût est presque trivial à mes yeux - le codage en dur est la meilleure idée ici.
Edit : Le doublon proposé demande comment stocker un grand nombre de chaînes statiques, alors que ma question est quand dois-je coder en dur ces chaînes statiques.
convient-il aux chaînes codées en dur qui ne changeront probablement pas pendant la durée de vie d'une application? Bien sûr, je ne peux pas garantir à 100% qu'ils ne changeront pas, mais le risque par rapport au coût est presque trivial à peser à mes yeux - le codage en dur est la meilleure idée ici
Il me semble que vous avez répondu à votre propre question.
L'un des plus grands défis auxquels nous sommes confrontés est de séparer les éléments susceptibles de changer de ceux qui ne changeront pas. Certaines personnes deviennent dingues et déversent absolument tout ce qu'elles peuvent dans un fichier de configuration. D'autres vont à l'autre extrême et nécessitent une recompilation, même pour les changements les plus évidents.
J'irais avec l'approche la plus simple à mettre en œuvre jusqu'à ce que je trouve une raison impérieuse de la rendre plus compliquée.
Vous raisonnez à la mauvaise portée.
Vous n'avez pas codé en dur uniquement les verbes individuels. Vous avez codé en dur la langue et ses règles . Ceci, à son tour, signifie que votre application ne peut pas être utilisée pour une autre langue et ne peut pas être étendue avec d'autres règles.
Si telle est votre intention (c'est-à-dire de l'utiliser uniquement en français), c'est la bonne approche, à cause de YAGNI. Mais vous admettez que vous souhaitez également l'utiliser plus tard pour d'autres langues, ce qui signifie que très bientôt, vous devrez de toute façon déplacer la partie codée en dur dans les fichiers de configuration. La dernière question est:
Allez-vous, avec une certitude proche de 100%, dans un avenir proche, étendre l'application à d'autres langues? Si c'est le cas, vous auriez dû exporter des choses vers fichiers JSON ou XML (pour les mots, des parties des mots, etc.) et langages dynamiques (pour les règles) maintenant à la place de vous forcer à réécrire la majeure partie de votre application.
Ou il n'y a qu'une faible probabilité que l'application soit étendue quelque part dans le futur, auquel cas YAGNI dicte que l'approche la plus simple (celle que vous utilisez en ce moment) est la meilleure?
À titre d'illustration, prenez le vérificateur d'orthographe de Microsoft Word. À votre avis, combien de choses sont codées en dur?
Si vous développez un processeur de texte, vous pouvez commencer par un moteur d'orthographe simple avec des règles codées en dur et même des mots codés en dur: if Word == "musik": suggestSpelling("music");
. Rapidement, vous commencerez à déplacer des mots, puis à vous exclure de votre code. Autrement:
Comme vous l'avez souligné:
Très peu de règles du français pourraient s'appliquer au japonais.
Dès que vous codez en dur les règles d'une langue, toutes les autres nécessiteront de plus en plus de code, surtout compte tenu de la complexité des langues naturelles.
Un autre sujet est de savoir comment vous exprimez ces différentes règles, sinon par le biais de code. En fin de compte, vous pouvez constater qu'un langage de programmation est le meilleur outil pour cela. Dans ce cas, si vous devez étendre le moteur sans le recompiler, langages dynamiques peut être une bonne alternative.
Les chaînes doivent être extraites dans un fichier de configuration ou une base de données lorsque les valeurs peuvent changer indépendamment à partir de la logique du programme.
Par exemple:
Extraction de textes d'interface utilisateur dans des fichiers de ressources. Cela permet à un non-programmeur de modifier et de relire les textes, et cela permet d'ajouter de nouvelles langues en ajoutant de nouveaux fichiers de ressources localisés.
Extraction des chaînes de connexion, des URL vers des services externes, etc. vers des fichiers de configuration. Cela vous permet d'utiliser différentes configurations dans différents environnements et de modifier les configurations à la volée car elles peuvent avoir besoin de changer pour des raisons externes à votre application.
Un correcteur orthographique qui a un dictionnaire de mots pour vérifier. Vous pouvez ajouter de nouveaux mots et langues sans modifier la logique du programme.
Mais il y a aussi une surcharge de complexité avec l'extraction vers la configuration, et cela n'a pas toujours de sens.
Les chaînes peuvent être codées en dur lorsque la chaîne réelle ne peut pas changer sans changer la logique du programme.
Exemples:
Dans votre cas, je pense qu'il est clair que les mots font partie intégrante de la logique du programme (puisque vous construisez un conjugateur avec des règles spécifiques pour des mots spécifiques), et extraire ces mots dans un fichier externe n'a aucune valeur.
Si vous ajoutez une nouvelle langue, vous devrez de toute façon ajouter un nouveau code, car chaque langue a une logique de conjugaison spécifique.
Certains ont suggéré que vous pourriez ajouter une sorte de moteur de règles qui vous permet de spécifier des règles de conjugaison pour des langues arbitraires, de sorte que de nouvelles langues pourraient être ajoutées uniquement par configuration. Réfléchissez bien avant de vous engager sur cette voie, car les langues humaines sont merveilleusement étranges, vous avez donc besoin d'un moteur de règles très expressif. Vous seriez fondamentalement inventant un nouveau langage de programmation (une conjugaison DSL) pour un bénéfice douteux. Mais vous disposez déjà d'un langage de programmation qui peut faire tout ce dont vous avez besoin. En tout cas, YAGNI.
Je suis d'accord à 100% avec la réponse de Dan Pichelman, mais j'aimerais ajouter une chose. La question que vous devez vous poser ici est "qui va maintenir/étendre/corriger la liste de mots?". Si c'est toujours la personne qui maintient également les règles d'un langage spécifique (le développeur en particulier, je suppose que vous), il est inutile d'utiliser un fichier de configuration externe si cela rend les choses plus complexes - vous n'obtiendrez aucun avantage de cette. De ce point de vue, il sera logique de coder en dur de telles listes de mots même si vous avez pour les modifier de temps en temps, tant qu'il suffit de fournir une nouvelle liste dans le cadre d'un nouvelle version.
(D'un autre côté, s'il y a une légère chance que quelqu'un d'autre soit en mesure de maintenir la liste à l'avenir, ou si vous devez modifier les listes Word sans déployer une nouvelle version de votre application, utilisez un fichier distinct.)
Même si le codage en dur semble correct ici, et mieux que le chargement dynamique de fichiers de configuration, je recommanderais toujours de faire strictement séparer votre des données (le dictionnaire des verbes) de l'algorithme . Vous pouvez les compiler directement dans votre application dans le processus de génération.
Cela vous fera économiser beaucoup de temps avec l'entretien de la liste. Dans votre VCS, vous pouvez facilement identifier si un commit a changé l'algorithme, ou simplement corriger un bug de conjugaison. En outre, la liste devra peut-être être ajoutée à l'avenir pour les cas que vous n'avez pas pris en compte. Surtout, le nombre des 32 verbes irréguliers que vous avez comptés ne semble pas être exact. Bien que ceux-ci semblent couvrir ceux couramment utilisés, j'ai trouvé des références à 1 ou même 5 d'entre eux.
La partie importante est la séparation des préoccupations. Comment y parvenir est moins pertinent. c'est-à-dire Java est très bien.
Indépendamment de la façon dont les règles sont exprimées, devez-vous ajouter une langue pour modifier une règle: combien de code et de fichiers devez-vous modifier?
Idéalement, l'ajout d'une nouvelle langue devrait être possible en ajoutant un fichier 'english.xml' ou un nouvel objet 'EnglishRules implements ILanguageRules'. Un fichier texte (JSON/XML) vous offre un avantage si vous souhaitez le modifier en dehors de votre cycle de vie de génération, mais nécessite une grammaire complexe, une analyse syntaxique et sera plus difficile à déboguer. Un fichier de code (Java) vous permet d'exprimer des règles complexes de manière plus simple, mais nécessite une reconstruction.
Je commencerais par une simple Java API derrière une interface agnostique en langage propre - comme vous en avez besoin dans les deux cas. Vous pouvez toujours ajouter une implémentation de cette interface soutenue par un fichier XML plus tard si vous le souhaitez , mais je ne vois pas la nécessité de s'attaquer à ce problème immédiatement (ou jamais).