Поэтому, пытаясь написать программу для спряжения глаголов (алгоритмически, а не через набор данных) для французского языка, я столкнулся с небольшой проблемой.
Алгоритм спряжения глаголов на самом деле довольно прост для 17-ти или около того случаев глаголов и работает по определенному шаблону для каждого случая; таким образом, суффиксы сопряжения для этих 17 классов являются статическими и (очень вероятно) не изменятся в ближайшее время. Например:
// 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"]
};
Это интонационные суффиксы для наиболее распространенного класса глаголов во французском языке.
Существуют и другие классы глаголов (неправильных), чьи спряжения также, скорее всего, останутся неизменными в течение следующего столетия или двух. Так как они нерегулярны, их полные спряжения должны быть включены статически, потому что они не могут быть надежно сопряжены с шаблоном (есть также [по моим подсчетам] 32 неправильных числа). Например:
// "ê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"]
};
Я мог бы поместить все это в XML или даже JSON и десериализовать это, когда это необходимо использовать, но есть ли смысл? Эти строки являются частью естественного языка, который меняется, но медленными темпами.
Я обеспокоен тем, что, выполнив «правильный» путь и десериализовав некоторый источник данных, я не только усложнил проблему, которая не должна быть сложной, но я также полностью откатился назад по всей цели алгоритмический подход: не использовать источник данных! В C # я мог бы просто создать класс в namespace Verb.Conjugation
(например class Irregular
) для размещения этих строк в перечисляемом типе или что-то в этом роде, вместо того, чтобы вставлять их в XML и создавать class IrregularVerbDeserializer
.
Поэтому вопрос: уместно ли жестко строк кода, которые очень маловероятно , чтобы изменения в течение жизни приложения? Конечно, я не могу гарантировать 100%, что они не изменятся, но риск против стоимости почти тривиален в моих глазах - жесткое кодирование - лучшая идея здесь.
Изменить : предложенный дубликат спрашивает, как хранить большое количество статических строк , в то время как мой вопрос, когда я должен жестко кодировать эти статические строки .
Ответы:
Мне кажется, что вы ответили на свой вопрос.
Одна из самых больших проблем, с которыми мы сталкиваемся, - это отделить то, что может измениться, от того, что не изменится. Некоторые люди сходят с ума и сбрасывают абсолютно все, что могут, в файл конфигурации. Другие переходят в другую крайность и требуют перекомпиляции даже для самых очевидных изменений.
Я бы использовал самый простой подход для реализации, пока не нашел вескую причину усложнить его.
источник
French.Verb.Irregular.Etre
который будет содержать данные из моего вопроса. Я думаю, что это хорошо работает;)if (num == 0xFFD8)
). Этот пример должен стать чем-то похожимif (num == JPEG_MAGIC_NUMBER)
почти во всех случаях для удобства чтения. Я просто указываю на это, потому что слово «жесткое кодирование» часто поднимает волоски на шеях людей (таких как моя) из-за этого альтернативного значения слова.JPEG_START_OF_IMAGE_MARKER
?Вы рассуждаете не в том направлении.
Вы не закодировали только отдельные глаголы. Вы жестко закодировали язык и его правила . Это, в свою очередь, означает, что ваше приложение не может быть использовано для какого-либо другого языка и не может быть расширено другими правилами.
Если это ваше намерение (то есть использовать его только для французского языка), то это правильный подход, потому что YAGNI. Но вы признаете, что хотите использовать его позже и для других языков, что будет означать, что очень скоро вам все равно придется перенести все жестко закодированные части в файлы конфигурации. Остается вопрос:
Будете ли вы с уверенностью, близкой к 100%, в ближайшем будущем распространять приложение на другие языки? Если это так, вы должны были экспортировать вещи в файлы JSON или XML (для слов, частей слов и т. Д.) И динамические языки (для правил) прямо сейчас, вместо того, чтобы заставлять себя переписывать основную часть вашего приложения.
Или существует лишь небольшая вероятность того, что приложение будет расширено где-то в будущем, и в этом случае YAGNI диктует, что самый простой подход (тот, который вы используете прямо сейчас) лучше?
В качестве иллюстрации возьмите проверку правописания в Microsoft Word. Как вы думаете, сколько вещей запрограммировано?
Если вы разрабатываете текстовый процессор, вы могли бы начать с простым орфографическим двигателем с HARDCODED правил и даже HARDCODED словом:
if word == "musik": suggestSpelling("music");
. Быстро, вы начнете перемещать слова, а затем будете править вне вашего кода. Иначе:Как вы подчеркнули себя:
Как только вы жестко закодируете правила для языка, каждому другому потребуется все больше и больше кода, особенно учитывая сложность естественных языков.
Другой вопрос, как вы выражаете эти разные правила, если не через код. В конечном счете, вы можете обнаружить, что язык программирования - лучший инструмент для этого. В этом случае, если вам нужно расширить движок, не перекомпилируя его, динамические языки могут быть хорошей альтернативой.
источник
LanguageProcessor
класс с несколькими подклассами. (По сути, «файл конфигурации» на самом деле является классом)Строки должны быть извлечены в файл конфигурации или базу данных, когда значения могут изменяться независимо от логики программы.
Например:
Извлечение текстов пользовательского интерфейса в файлы ресурсов. Это позволяет не программисту редактировать и корректировать тексты, и это позволяет добавлять новые языки, добавляя новые локализованные файлы ресурсов.
Извлечение строк подключения, ссылок на внешние службы и т. Д. В файлы конфигурации. Это позволяет вам использовать разные конфигурации в разных средах и изменять конфигурации на лету, потому что они могут нуждаться в изменении по причинам, не зависящим от вашего приложения.
Проверка орфографии, в которой есть словарь слов для проверки. Вы можете добавлять новые слова и языки без изменения логики программы.
Но есть также сложности с извлечением в конфигурацию, и это не всегда имеет смысл.
Строки могут быть жестко закодированы, когда фактическая строка не может измениться без изменения логики программы.
Примеры:
В вашем случае я думаю, что ясно, что слова являются неотъемлемой частью логики программы (поскольку вы создаете конъюгатор со специальными правилами для конкретных слов), и извлечение этих слов во внешний файл не имеет значения.
Если вы добавляете новый язык, вам все равно нужно будет добавить новый код, поскольку каждый язык имеет определенную логику сопряжения.
Некоторые полагают, что вы можете добавить какой-то механизм правил, который позволяет вам задавать правила сопряжения для произвольных языков, чтобы новые языки могли добавляться исключительно по конфигурации. Прежде чем идти по этому пути, тщательно подумайте, потому что человеческие языки удивительно странные, поэтому вам нужен очень выразительный механизм правил. Вы бы в основном изобрели новый язык программирования (сопряженный DSL) для сомнительной выгоды. Но у вас уже есть язык программирования, который может делать все, что вам нужно. В любом случае, ЯГНИ.
источник
Я полностью согласен с ответом Дэна Пихельмана, но я хотел бы добавить одну вещь. Вопрос, который вы должны задать себе здесь: «кто будет поддерживать / расширять / исправлять список слов?». Если это всегда человек, который также поддерживает правила определенного языка (конкретный разработчик, я полагаю, вы), то нет смысла использовать внешний файл конфигурации, если это усложняет ситуацию - вы не получите никакой выгоды от это. С этой точки зрения, имеет смысл жестко закодировать такие списки слов, даже если вам придется время от времени изменять их, если этого достаточно для доставки нового списка как части новой версии.
(С другой стороны, если есть небольшая вероятность, что кто-то другой должен иметь возможность поддерживать список в будущем, или если вам нужно изменить списки слов без развертывания новой версии вашего приложения, используйте отдельный файл.)
источник
Даже несмотря на то, что здесь жесткое кодирование выглядит хорошо и лучше, чем динамическая загрузка файлов конфигурации, я все же рекомендую вам строго отделить ваши данные (словарь глаголов) от алгоритма . Вы можете скомпилировать их прямо в ваше приложение в процессе сборки.
Это избавит вас от хлопот с ведением списка. В вашей VCS вы можете легко определить, действительно ли коммит изменил алгоритм, или просто исправить ошибку сопряжения. Кроме того, список может потребоваться добавить в будущем для случаев, которые вы не рассматривали. В частности, число 32 неправильных глаголов, которые вы сосчитали, не кажется точным. В то время как те, кажется, покрывают обычно используемые, я нашел ссылки на 133 или даже 350 из них.
источник
Важной частью является разделение интересов. То, как вы этого достигнете, менее актуально то есть Java в порядке.
Независимо от того, как выражены правила, нужно ли вам добавлять язык изменения правила: сколько кода и файлов нужно отредактировать?
В идеале, добавление нового языка должно быть возможно либо путем добавления файла «english.xml», либо нового объекта «EnglishRules реализует ILanguageRules». Текстовый файл (JSON / XML) дает вам преимущество, если вы хотите изменить его вне жизненного цикла сборки, но при этом требуется сложная грамматика, синтаксический анализ и отладка будет сложнее. Файл кода (Java) позволяет вам выразить сложные правила более простым способом, но требует перестройки.
Я бы начал с простого Java API за чистым языковым интерфейсом, который вам нужен в обоих случаях. Вы всегда можете добавить реализацию этого интерфейса, поддерживаемую XML-файлом позже, если хотите, но я не вижу необходимости решать эту проблему немедленно (или когда-либо).
источник