Entonces, en mis esfuerzos por escribir un programa para conjugar verbos (algorítmicamente, no a través de un conjunto de datos) para el francés, me encontré con un pequeño problema.
El algoritmo para conjugar los verbos es en realidad bastante simple para los más o menos 17 casos de verbos, y se ejecuta en un patrón particular para cada caso; por lo tanto, los sufijos de conjugación para estas 17 clases son estáticos y (muy probablemente) no cambiarán en el corto plazo. Por ejemplo:
// 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"]
};
Estos son sufijos de inflexión para la clase de verbo más común en francés.
Hay otras clases de verbos (irregulares), cuyas conjugaciones probablemente también permanecerán estáticas durante el próximo siglo o dos. Como son irregulares, sus conjugaciones completas deben incluirse estáticamente, porque no pueden conjugarse de manera confiable a partir de un patrón (también hay solo [según mi recuento] 32 irregulares). Por ejemplo:
// "ê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"]
};
Podría poner todo esto en XML o incluso JSON y deserializarlo cuando sea necesario, pero ¿hay algún punto? Estas cadenas son parte del lenguaje natural, que cambia, pero a un ritmo lento.
Mi preocupación es que al hacer las cosas de la manera "correcta" y deserializar alguna fuente de datos, no solo he complicado el problema que no tiene por qué ser complicado, sino que también he retrocedido por completo en todo el objetivo del enfoque algorítmico: ¡ no usar una fuente de datos! En C #, podría crear una clase bajo namespace Verb.Conjugation
(por ejemplo class Irregular
) para alojar estas cadenas en un tipo enumerado o algo así, en lugar de rellenarlas en XML y crear un class IrregularVerbDeserializer
.
Entonces la pregunta: ¿ es apropiado codificar cadenas que es muy poco probable que cambien durante la vida útil de una aplicación? Por supuesto, no puedo garantizar al 100% que no cambien, pero el riesgo frente al costo es casi trivial para mí: la mejor idea aquí es la codificación dura.
Editar : El duplicado propuesto pregunta cómo almacenar una gran cantidad de cadenas estáticas , mientras que mi pregunta es cuándo debo codificar estas cadenas estáticas .
Respuestas:
Me parece que respondiste tu propia pregunta.
Uno de los mayores desafíos que enfrentamos es separar las cosas que probablemente cambien de las que no cambiarán. Algunas personas se vuelven locas y vuelcan absolutamente todo lo que pueden en un archivo de configuración. Otros van al otro extremo y requieren una recompilación incluso para los cambios más obvios.
Seguiría el enfoque más fácil de implementar hasta que encontrara una razón convincente para hacerlo más complicado.
fuente
French.Verb.Irregular.Etre
que contendría los datos de mi pregunta. Creo que funciona bien;)if (num == 0xFFD8)
). Ese ejemplo debería convertirse en algo parecidoif (num == JPEG_MAGIC_NUMBER)
en casi todos los casos por razones de legibilidad. Solo lo señalo porque la palabra "codificación" a menudo levanta pelos en el cuello de las personas (como la mía) debido a este significado alternativo de la palabra.JPEG_START_OF_IMAGE_MARKER
¿ Seguro ?Estás razonando en el ámbito equivocado.
No ha codificado solo verbos individuales. Has codificado el idioma y sus reglas . Esto, a su vez, significa que su aplicación no se puede usar para ningún otro idioma y no se puede extender con otras reglas.
Si esta es su intención (es decir, usarla solo para francés), este es el enfoque correcto, debido a YAGNI. Pero admite que desea usarlo más tarde también para otros idiomas, lo que significa que muy pronto, tendrá que mover toda la parte codificada a los archivos de configuración de todos modos. La pregunta restante es:
¿Podrá, con una certeza cercana al 100%, en un futuro próximo, extender la aplicación a otros idiomas? Si es así, debería haber estado exportando cosas a archivos JSON o XML (para palabras, partes de las palabras, etc.) e idiomas dinámicos (para reglas) en este momento en lugar de obligarse a reescribir la mayor parte de su aplicación.
¿O solo hay una pequeña probabilidad de que la aplicación se extienda en algún lugar en el futuro, en cuyo caso YAGNI dicta que el enfoque más simple (el que está utilizando en este momento) es el mejor?
Como ilustración, tome el corrector ortográfico de Microsoft Word. ¿Cuántas cosas crees que están codificadas?
Si está desarrollando un procesador de texto, se puede empezar por un motor de ortografía sencilla con las normas Hardcoded y palabras, incluso Hardcoded:
if word == "musik": suggestSpelling("music");
. Rápidamente, comenzará a mover palabras, luego se regirá a sí mismas fuera de su código. De otra manera:Como te destacaste a ti mismo:
Tan pronto como codifique las reglas de un idioma, cada uno requerirá más y más código, especialmente dada la complejidad de los lenguajes naturales.
Otro tema es cómo expresa esas diferentes reglas, si no a través del código. En última instancia, puede encontrar que un lenguaje de programación es la mejor herramienta para eso. En ese caso, si necesita extender el motor sin volver a compilarlo, los lenguajes dinámicos pueden ser una buena alternativa.
fuente
LanguageProcessor
clase con múltiples subclases. (Efectivamente, el "archivo de configuración" es en realidad una clase)Las cadenas deben extraerse a un archivo de configuración o base de datos cuando los valores puedan cambiar independientemente de la lógica del programa.
Por ejemplo:
Extracción de textos de IU a archivos de recursos. Esto permite que un no programador edite y corrija los textos, y permite agregar nuevos idiomas al agregar nuevos archivos de recursos localizados.
Extracción de cadenas de conexión, direcciones URL a servicios externos, etc. a archivos de configuración. Esto le permite usar diferentes configuraciones en diferentes entornos y cambiar las configuraciones sobre la marcha porque pueden necesitar cambiar por razones externas a su aplicación.
Un corrector ortográfico que tiene un diccionario de palabras para verificar. Puede agregar nuevas palabras e idiomas sin modificar la lógica del programa.
Pero también hay una sobrecarga de complejidad con la extracción a la configuración, y no siempre tiene sentido.
Las cadenas se pueden codificar cuando la cadena real no puede cambiar sin cambiar la lógica del programa.
Ejemplos:
En su caso, creo que está claro que las palabras son una parte integrada de la lógica del programa (ya que está construyendo un conjugador con reglas específicas para palabras específicas), y extraer estas palabras a un archivo externo no tiene ningún valor.
Si agrega un nuevo idioma, deberá agregar un nuevo código de todos modos, ya que cada idioma tiene una lógica de conjugación específica.
Algunos han sugerido que podría agregar algún tipo de motor de reglas que le permita especificar reglas de conjugación para lenguajes arbitrarios, de modo que los nuevos lenguajes puedan agregarse únicamente por configuración. Piensa con mucho cuidado antes de seguir ese camino, porque los lenguajes humanos son maravillosamente extraños, por lo que necesitas un motor de reglas muy expresivo. Básicamente, estaría inventando un nuevo lenguaje de programación (un DSL de conjugación) para dudoso beneficio. Pero ya tiene un lenguaje de programación a su disposición que puede hacer todo lo que necesite. En cualquier caso, YAGNI.
fuente
Estoy 100% de acuerdo con la respuesta de Dan Pichelman, pero me gustaría agregar algo. La pregunta que debe hacerse aquí es "¿quién va a mantener / ampliar / corregir la lista de palabras?". Si siempre es la persona quien también mantiene las reglas de un lenguaje específico (el desarrollador particular, supongo que usted), entonces no tiene sentido usar un archivo de configuración externo si esto hace las cosas más complejas; no obtendrá ningún beneficio de esta. Desde este punto de vista, tendrá sentido codificar tales listas de palabras incluso si tiene que cambiarlas de vez en cuando, siempre que sea suficiente para entregar una nueva lista como parte de una nueva versión.
(Por otro lado, si hay una pequeña posibilidad de que alguien más pueda mantener la lista en el futuro, o si necesita cambiar las listas de palabras sin implementar una nueva versión de su aplicación, use un archivo separado).
fuente
Incluso aunque la codificación parece correcta aquí, y mejor que cargar dinámicamente los archivos de configuración, todavía recomendaría que separe estrictamente sus datos (el diccionario de verbos) del algoritmo . Puede compilarlos directamente en su aplicación en el proceso de compilación.
Esto le ahorrará muchos problemas con el mantenimiento de la lista. En su VCS puede identificar fácilmente si una confirmación cambió el algoritmo o simplemente solucionó un error de conjugación. Además, es posible que la lista deba agregarse en el futuro para casos que no consideró. Especialmente, el número de los 32 verbos irregulares que contó no parece ser exacto. Si bien estos parecen cubrir los de uso común, encontré referencias a 133 o incluso 350 de ellos.
fuente
La parte importante es la separación de la preocupación. Cómo lograr eso es menos relevante. es decir, Java está bien.
Independientemente de cómo se expresan las reglas, ¿debe agregar un idioma para cambiar una regla: cuántos códigos y archivos tiene que editar?
Idealmente, debería ser posible agregar un nuevo idioma agregando un archivo 'english.xml' o un nuevo objeto 'EnglishRules implementa ILanguageRules'. Un archivo de texto (JSON / XML) le brinda una ventaja si desea cambiarlo fuera de su ciclo de vida de compilación, pero requiere una gramática compleja, análisis y será más difícil de depurar. Un archivo de código (Java) le permite expresar reglas complejas de una manera más simple, pero requiere una reconstrucción.
Comenzaría con una API Java simple detrás de una interfaz independiente de lenguaje limpio, ya que lo necesita en ambos casos. Siempre puede agregar una implementación de esa interfaz respaldada por un archivo XML más adelante si lo desea, pero no veo la necesidad de abordar ese problema de inmediato (o nunca).
fuente