Сначала немного фона. Я кодирую поиск по возрасту -> Оценить. Есть 7 возрастных скобок, поэтому таблица поиска состоит из 3 столбцов (От | До | Оценить) с 7 строками. Значения редко меняются - это законодательные нормы (первый и третий столбцы), которые остаются неизменными в течение 3 лет. Я подумал, что самый простой способ сохранить эту таблицу без жесткого кодирования - это использовать ее в базе данных в глобальной таблице конфигурации, в виде единого текстового значения, содержащего CSV (так как "65,69,0.05,70,74,0.06" уровни 65-69 и 70-74 будут сохранены). Относительно легко разобрать, затем использовать.
Затем я понял, что для реализации этого мне нужно будет создать новую таблицу, репозиторий для ее обертывания, тесты уровня данных для репозитория, модульные тесты вокруг кода, который раскрывает CSV в таблицу, и тесты вокруг самого поиска. Единственное преимущество всей этой работы - избегание жесткого кодирования таблицы поиска.
Говоря с пользователями (которые в настоящее время используют таблицу поиска напрямую - просматривая печатную копию), в значительной степени складывается мнение, что «ставки никогда не меняются». Очевидно, что это на самом деле не правильно - ставки были созданы только три года назад, и в прошлом вещи, которые «никогда не менялись», имели привычку меняться - поэтому для меня, чтобы защитно программировать это, я определенно не должен хранить таблицу поиска в приложение.
За исключением случаев, когда я думаю, что ЯГНИ . Функция, которую я реализую, не указывает, что ставки будут меняться. Если тарифы меняются, они все равно будут меняться настолько редко, что обслуживание даже не рассматривается, и эта функция на самом деле не настолько критична, чтобы что-то могло повлиять на задержку между изменением тарифа и обновленным приложением.
Я в значительной степени решил, что ничего ценного не будет потеряно, если я жестко закодирую поиск, и я не слишком обеспокоен моим подходом к этой конкретной функции. У меня вопрос, как профессионал, правильно ли я обосновал это решение? Жесткое кодирование значений - это плохой дизайн, но попытка удаления значений из приложения, похоже, нарушает принцип YAGNI.
РЕДАКТИРОВАТЬ Чтобы уточнить вопрос, я не беспокоюсь о фактической реализации. Я обеспокоен тем, что я могу сделать что-то быстрое, плохое и оправдать это, сказав YAGNI, или я могу использовать более оборонительный подход, требующий больших усилий, который даже в лучшем случае в конечном итоге приносит мало пользы. Как профессиональный программист, мое решение реализовать дизайн, который, как я знаю, ошибочно, сводится просто к анализу затрат / выгод?
РЕДАКТИРОВАТЬ Хотя все ответы были очень интересными, так как я думаю, что это сводится к выбору индивидуального дизайна, я думаю, что лучшие ответы были @ Corbin's и @EZ Hart's, поскольку они затрагивают вещи, которые я не учел в вопросе:
- ложная дихотомия «правильного удаления жестко запрограммированных значений» путем перемещения их в базу данных против «эффективного применения YAGNI» с помощью жесткого кодирования. Существовал третий вариант размещения таблицы соответствия в конфигурации приложения, которая не влечет за собой лишних затрат правильного способа и без эффективности YAGNI. Мы, как правило, не ограничиваемся ни одним из решений, и затем все сводится к решению по соотношению цена / качество.
- генерация кода может уменьшить накладные расходы на перемещение жестко закодированных значений в базу данных, а также устраняет мое чрезмерно сложное решение обработать CSV в таблице. Потенциально это также добавляет проблему долгосрочного обслуживания сгенерированного кода, если основные требования изменяются для метода поиска. Все это только влияет на анализ затрат / выгод, и, вероятно, если бы у меня была такая автоматизация, я бы даже не подумал о жестком кодировании чего-то подобного.
Я помечаю ответ @ Corbin как правильный, потому что он меняет мои предположения о стоимости разработки, и я, вероятно, добавлю некоторые инструменты генерации кода в свой арсенал в ближайшем будущем.
Ответы:
Вы нашли недостаток в своем процессе разработки. Когда будет трудно сделать правильные вещи (создать таблицу, репо, тесты репо, сплющить тесты ...), разработчики найдут способ обойти это. Обычно это связано с неправильным поступком. В этом случае соблазнительно относиться к данным приложения как к логике приложения. Не делай этого. Вместо этого добавьте полезные средства автоматизации в процесс разработки. Мы используем CodeSmith для создания скучного, стандартного кода, который никто не хочет писать. После создания таблицы мы запускаем CodeSmith, и он генерирует DAO, DTO и заглушки для каждого из них.
В зависимости от технологий, которые вы используете, у вас должны быть похожие опции. Многие инструменты ORM будут генерировать модели из существующей схемы. Миграции Rails работают в обратном направлении - таблицы из моделей. Мета-программирование в динамических языках особенно эффективно при устранении стандартного кода. Вам придется работать немного усерднее, чтобы сгенерировать все, что вам нужно, если у вас есть сложное многоуровневое приложение, но оно того стоит. Не позволяйте чувству «вау, это боль в шее» помешать вам поступить правильно.
Да, и не храните ваши данные в формате, который требует дополнительной обработки (CSV). Это просто добавляет дополнительные шаги, которые требуют вашего внимания и тестирования.
источник
Отключить и расширить ответ @ Thorbjørn Ravn Andersen: Хорошее начало - держать расчет / поиск в одном месте.
Ваш мыслительный процесс защиты против ЯГНИ является распространенной проблемой. В этом случае я бы посоветовал ему сообщить еще две вещи.
Во-первых, как были представлены требования пользователя? Они указали возможность редактирования ставок? Если нет, то является ли дополнительная сложность частью того, за что вы можете выставить счет или нет? (или если вы работаете в штате, что вы можете вместо этого тратить время на другую работу?)
Во-вторых, и, возможно, что еще более важно, простое редактируемое изменение вряд ли выполнит фактическое требование перед лицом законодательного изменения. Если и когда ставки изменятся, вероятно, наступит дата сокращения и некоторая обработка до и после. Кроме того, если тот же интерфейс должен затем выполнять какой-либо вид обработки претензий с задним числом, то может потребоваться поиск правильной ставки на основе даты вступления в силу, а не фактической даты.
Короче говоря, я отмечаю, что фактическое редактируемое требование вполне может быть довольно сложным, поэтому, если оно не будет уточнено, простое, вероятно, лучше.
Удачи
источник
Сделайте фактический поиск библиотечной функцией. Затем вы можете увидеть весь код, используя этот поиск, в своем исходном репозитории, чтобы вы знали, какие программы необходимо обновить при изменении тарифов.
источник
PensionRateLookup
класса), который затем используется глобально. Я хотел бы сделать это независимо от того, хранится ли он вне приложения или жестко закодирован, таким образомPensionRateLookup
необходимо поддерживать только реализацию класса. Моя проблема в том, как я использовал YAGNI, чтобы прийти к выводу, что жесткое кодирование таблицы поиска приемлемо.Дай мне посмотреть, правильно ли я понял твой вопрос. У вас есть 2 варианта реализации функции: либо вы жестко кодируете значение, и ваша функция проста в реализации (хотя вам не нравится часть с жестким кодом), либо у вас есть очень большие усилия, чтобы «повторить» много дел, которые сделаны Таким образом, вы можете развивать свои функции в чистом виде. Это верно?
Первое, что приходит мне в голову: «Самое важное в знании хороших практик - это знать, когда тебе лучше без них».
В этом случае усилия очень высоки, так что вы можете сделать это аккуратно, шансы побочного эффекта этого изменения велики, а отдача, которую вы получите, мала (как вы объяснили, похоже, что это не так). изменение).
Я бы использовал подход с жестким кодом (но подготовил его, чтобы он был гибким в будущем), и, в случае изменения этой скорости в будущем, воспользуюсь возможностью реорганизовать весь этот плохой дизайн раздела кода. Таким образом, время и стоимость могут быть оценены правильно, а стоимость изменения вашего жестко заданного значения будет минимальной.
Это был бы мой подход :)
источник
Это элемент, который «не изменится», пока не изменится. Это неизбежно, что это изменится, но это время может быть немного далеко.
Ваше обоснование верно. В это время клиент не просил о возможности легко изменить эти тарифы. Как таковой, ЯГНИ.
Однако вам не нужен код, который получает доступ к вашим ставкам и интерпретирует результаты, разбросанные по всей базе кода. Хороший ОО-проект позволил бы вам инкапсулировать внутреннее представление ваших ставок в классе и раскрыть только один или два метода, необходимых для использования данных.
Вам понадобится эта инкапсуляция для предотвращения ошибок копирования и вставки или необходимость выполнения рефакторинга для всего кода, который использует скорости, когда вам нужно внести изменения во внутреннее представление. Когда вы принимаете эту начальную меру предосторожности, более сложный подход может быть простым обменом и заменой более функциональной версии.
Кроме того, назовите ограничение текущего дизайна для клиента. Скажите им, что в интересах поддержания графика вы жестко закодировали значения - что требует изменения кодировки для их обновления. Таким образом, когда им становится известно об ожидаемых изменениях ставок в связи с новым законодательством, они могут просто обновить таблицу поиска или выполнить более сложные изменения в это время. Но положите это решение на колени.
источник
Разделите разницу и поместите данные о скорости в настройку конфигурации. Вы можете использовать формат CSV, который у вас уже есть, избегая ненужных накладных расходов на базу данных, и если изменение когда-либо понадобится, это будет изменение, которое клиент сможет внести без перекомпиляции / переустановки и без ошибок. вокруг в базе данных - они могут просто редактировать файл конфигурации.
Обычно, когда вы смотрите на выбор между двумя крайностями (нарушение YAGNI или жесткое кодирование динамических данных), лучший ответ - где-то посередине. Остерегайтесь ложных дихотомий.
Это предполагает, что вся ваша конфигурация находится в файлах; если это где-то сложно, как в реестре, вы, вероятно, должны игнорировать этот совет :)
источник
Только что создал таблицу БД. (Вы думали о том, чтобы хранить всю таблицу в одном файле, вы сошли с ума?)
В таблице нужно 2 поля НЕ 3. Возраст и рейтинг. Следующая строка содержит верхнее значение! Вы нормализуетесь, даже не подозревая об этом!
Вот Sql, чтобы получить тариф для человека в возрасте 67 лет.
Не пытайтесь сделать экран технического обслуживания, поскольку он выходит за рамки. Если они попросят об этом позже, сделайте запрос на изменение и сделайте это.
РЕДАКТИРОВАТЬ: Как уже говорили другие, сохранить код централизованно получает ставку, в случае если вся структура ставки меняется.
источник
Я согласен с большинством ответов. Я также добавил бы, что согласованность с остальной частью приложения важна. Если это единственное место в коде с жестко закодированными значениями, это, вероятно, удивит сопровождающих. Это особенно верно, если это большая и стабильная база кода. Если это небольшая программа, поддерживаемая вами, решение менее важно.
У меня есть далекие воспоминания о том, что я читал известного парня из Agile / OOP (например, Дейва Томаса, Кента Бека или кого-то другого), который говорил, что их практическое правило для дублирования кода было два и только два: не реорганизуйте первый раз, когда вы что-то дублируете, так как Вы можете написать это только дважды в своей жизни. Но в третий раз ...
Это не совсем решает вопрос, так как вы спрашиваете YAGNI, но я думаю, что это говорит об общей гибкости гибких правил. Смысл гибкого подхода заключается в том, чтобы адаптироваться к ситуации и двигаться вперед.
источник
Жесткий код в функции.
источник