Donc, dans mes efforts pour écrire un programme de conjugaison de verbes (en utilisant un jeu de données) pour le français, j'ai rencontré un léger problème.
L'algorithme permettant de conjuguer les verbes est en fait assez simple pour les cas de verbes d'environ 17 ans, et utilise 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 très probablement statiques pendant un ou deux siècles. Étant donné qu’elles sont irrégulières, leurs conjugaisons complètes doivent être incluses statiquement, car elles ne peuvent pas être conjuguées de manière fiable à partir d’un motif (il n’ya également que 32 personnes irrégulières). 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 au besoin, mais y a-t-il un objectif? Ces chaînes font partie du langage naturel, qui change, mais à un rythme lent.
Ce qui me préoccupe, c’est qu’en agissant de la manière «correcte» et en désérialisant certaines sources de données, j’ai non seulement compliqué le problème, qui n’a pas besoin d’être compliqué, mais aussi complètement relégué au second plan. approche algorithmique: ne pas utiliser une source de données! En C #, je pourrais 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 du genre, au lieu de les insérer dans XML et de créer un fichier class IrregularVerbDeserializer
.
Donc, la question: est-il approprié de coder en dur des chaînes 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 rapport coût / risque est presque trivial à peser à 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 de savoir quand devrais-je coder en dur ces chaînes statiques .
Réponses:
Il me semble que vous avez répondu à votre propre question.
L'un des plus grands défis à relever consiste à séparer les éléments susceptibles de changer des éléments qui ne changeront pas. Certaines personnes deviennent fous et jettent 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.
Je choisirais l'approche la plus simple à mettre en œuvre jusqu'à ce que je trouve une raison impérieuse de compliquer les choses.
la source
French.Verb.Irregular.Etre
contenant par exemple les données de ma question. Je pense que ça marche très bien;)if (num == 0xFFD8)
). Cet exemple devrait devenir quelque chose commeif (num == JPEG_MAGIC_NUMBER)
dans presque tous les cas pour des raisons de lisibilité. Je le signale simplement parce que le mot "codage en dur" soulève souvent les cheveux sur le cou des gens (comme le mien) à cause de cette autre signification du mot.JPEG_START_OF_IMAGE_MARKER
?Vous raisonnez sur une mauvaise portée.
Vous n'avez pas codé en dur uniquement des verbes individuels. Vous avez codé en dur le langage 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 l’utiliser uniquement en français), c’est la bonne approche, à cause de YAGNI. Mais vous admettez vous-même que vous souhaitez l'utiliser ultérieurement pour d'autres langues également, ce qui signifie que très bientôt, vous devrez de toute façon transférer toute la partie codée en dur dans les fichiers de configuration. La question restante est:
Voulez-vous, avec une certitude proche de 100%, dans un avenir proche, étendre l'application à d'autres langues? Si tel est le cas, vous devriez déjà exporter des éléments vers des fichiers JSON ou XML (pour des mots, des parties de mots, etc.) et des langages dynamiques (pour des règles) au lieu de vous forcer à réécrire la majeure partie de votre application.
Ou bien, il existe une faible probabilité que l'application soit étendue quelque part dans le futur. Dans ce cas, YAGNI indique que l'approche la plus simple (celle que vous utilisez actuellement) est la meilleure?
À titre d’illustration, prenons le vérificateur d’orthographe de Microsoft Word. Combien de choses pensez-vous sont codées en dur?
Si vous développez un traitement de texte, vous pouvez commencer par une simple moteur d'orthographe avec les règles et même des mots codés en dur codées en dur:
if word == "musik": suggestSpelling("music");
. Rapidement, vous commencez à déplacer les mots, puis à se contrôler en dehors de votre code. Autrement:Comme vous l'avez souligné vous-même:
Dès que vous coderez en dur les règles d'une langue, toutes les autres exigeront de plus en plus de code, en particulier compte tenu de la complexité des langues naturelles.
Un autre sujet est la façon dont vous exprimez ces différentes règles, si ce n'est par le code. En fin de compte, vous constaterez peut-être qu'un langage de programmation est le meilleur outil pour cela. Dans ce cas, si vous avez besoin d'étendre le moteur sans le recompiler, les langages dynamiques peuvent constituer une bonne alternative.
la source
LanguageProcessor
classe avec plusieurs sous-classes. (En réalité, le "fichier de configuration" est en fait une classe)Les chaînes doivent être extraites dans un fichier de configuration ou une base de données lorsque les valeurs peuvent changer indépendamment de la logique du programme.
Par exemple:
Extraction de textes d'interface utilisateur dans des fichiers de ressources. Cela permet à un non-programmeur d'éditer et de relire les textes, et d'ajouter de nouvelles langues en ajoutant de nouveaux fichiers de ressources localisés.
Extraction de chaînes de connexion, d’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 devoir être modifiées pour des raisons externes à votre application.
Un correcteur orthographique qui a un dictionnaire de mots à vérifier. Vous pouvez ajouter de nouveaux mots et langues sans modifier la logique du programme.
Cependant, l'extraction vers la configuration entraîne une complexité supplémentaire qui 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 que l'extraction de ces mots dans un fichier externe n'a aucune valeur.
Si vous ajoutez une nouvelle langue, vous devrez quand même ajouter un nouveau code, car chaque langue a une logique de conjugaison spécifique.
Certains ont suggéré d'ajouter un type de moteur de règles permettant de spécifier des règles de conjugaison pour des langues arbitraires, afin que de nouvelles langues puissent être ajoutées uniquement par configuration. Réfléchissez bien avant de vous engager dans cette voie, car les langages humains sont merveilleusement étranges. Vous avez donc besoin d'un moteur de règles très expressif. Vous inventeriez essentiellement un nouveau langage de programmation (un DSL de conjugaison) pour un bénéfice douteux. Mais vous avez déjà à votre disposition un langage de programmation qui peut faire tout ce dont vous avez besoin. En tout cas, YAGNI.
la source
Je suis tout à fait d'accord avec la réponse de Dan Pichelman, mais je voudrais ajouter une chose. La question que vous devriez vous poser ici est "qui va maintenir / allonger / 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 vous), alors il n'y a aucun intérêt à utiliser un fichier de configuration externe si cela complique les choses - vous n'obtiendrez aucun avantage cette. De ce point de vue, il sera logique de coder en dur de telles listes de mots, même si vous devez les changer de temps en temps, dans la mesure où il suffit de fournir une nouvelle liste dans le cadre d'une nouvelle version.
(Par contre, s'il y a une faible chance que quelqu'un d'autre puisse être capable de maintenir la liste à l'avenir, ou si vous devez modifier les listes de mots sans déployer une nouvelle version de votre application, utilisez un fichier séparé.)
la source
Même si le codage en dur semble correct ici, et mieux que le chargement dynamique de fichiers de configuration, je vous recommande néanmoins de séparer strictement vos données (le dictionnaire des verbes) de l' algorithme . Vous pouvez les compiler directement dans votre application lors du processus de construction.
Cela vous fera économiser beaucoup de temps avec le maintien de la liste. Dans votre VCS, vous pouvez facilement identifier si un commit a bien changé l'algorithme, ou simplement corriger un bogue de conjugaison. En outre, la liste devra peut-être être ajoutée à l'avenir pour les cas non pris en compte. Surtout, le nombre de 32 verbes irréguliers que vous avez comptés ne semble pas être exact. Bien que ceux-ci semblent couvrir ceux qui sont couramment utilisés, j'ai trouvé des références à 133 voire 350 d'entre eux.
la source
La partie importante est la séparation des préoccupations. Comment vous y parvenez est moins pertinent. c'est-à-dire que Java va bien.
Indépendamment de la manière dont les règles sont exprimées, devriez-vous ajouter une langue pour modifier une règle: combien de codes 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 implémente ILanguageRules'. Un fichier texte (JSON / XML) vous donne un avantage si vous souhaitez le modifier en dehors de votre cycle de vie de génération, mais nécessitant 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 API Java derrière une interface agnostique en langage clair - comme vous en avez besoin dans les deux cas. Si vous le souhaitez, vous pouvez toujours ajouter ultérieurement une implémentation de cette interface avec un fichier XML, mais je ne vois pas la nécessité de traiter ce problème immédiatement (ou jamais).
la source