Избавление от жестко закодированных значений при работе с таблицами поиска и связанной бизнес-логикой - PullRequest
5 голосов
/ 30 октября 2009

Пример дела:

Мы создаем сервис аренды с использованием SQL Server. Информация о предметах, которые можно арендовать, хранится в таблице. Каждый элемент имеет состояние, которое может быть «Доступен», «Арендован» или «Сломан». Различные состояния находятся в таблице поиска.

Таблица ItemState:

идентификатор
1 «Доступен»
2 'Арендовано'
3 «Сломан»

В дополнение к этому у нас есть бизнес-правило, которое гласит, что всякий раз, когда элемент возвращается, его состояние изменяется с «Арендован» на «Доступен».
Это можно сделать с помощью оператора update, например «update Items set state = 1, где id = @ itemid». В коде приложения у нас может быть перечисление, которое отображается на идентификатор ItemState: s. Тем не менее, они содержат жестко закодированные значения, которые могут впоследствии привести к проблемам с техническим обслуживанием. Скажем, если бы разработчик изменил набор состояний, но забыл исправить связанный уровень бизнес-логики ...

Какие хорошие методы или альтернативные конструкции существуют для решения проблем такого типа?
Ссылки на соответствующие статьи также приветствуются в дополнение к прямым ответам.

Ответы [ 9 ]

5 голосов
/ 30 октября 2009

По моему опыту, это тот случай, когда у вас есть для жесткого кодирования, предпочтительно с использованием Enum, целочисленные значения которого соответствуют идентификаторам ваших таблиц поиска. Я не вижу ничего плохого в том, что «1» всегда «доступен» и т. Д.

3 голосов
/ 30 октября 2009

Большинство систем, которые я видел, жестко кодируют значения таблицы поиска и живут с ней. Это потому, что на практике кодовые таблицы редко меняются настолько, насколько вы думаете, они могли бы. И если они когда-либо изменятся, вам, как правило, нужно перекомпилировать любые программы, которые все равно используют этот DDL.

Тем не менее, если вы хотите сделать код обслуживаемым (похвальная цель), лучшим подходом было бы преобразование значений в файл свойств. Затем вы сможете позже отредактировать этот файл без необходимости перекодировать все приложение.

Ограничивающим фактором здесь является то, что ваше приложение зависит от своего внутреннего состояния от значения, которое вы получаете из справочной таблицы, что подразумевает определенную степень связи.

Для поиска, где приложение не не использует этот код (например, если ваша таблица кодов хранит список двухбуквенных кодов состояния для использования в раскрывающемся списке адресов), тогда Вы можете лениво загружать коды в объект и получать к ним доступ только при необходимости. Но это не сработает для того, что вы делаете.

2 голосов
/ 30 октября 2009

Если у вас есть таблицы поиска и перечисления, определенные в коде, у вас всегда есть проблема с синхронизацией их. Здесь мало что можно сделать. Оба эффективно живут в двух разных мирах и, как правило, не знают друг друга.

Вы можете отказаться от использования справочных таблиц и разрешить вашей бизнес-логике работать только с этими значениями. В этом случае вы упускаете возможность полагаться на ссылочную целостность, чтобы подтвердить свою целостность данных.

Другой вариант - создать приложение таким образом, чтобы эти значения никогда не использовались в вашем коде. Это означает перемещение части вашей бизнес-логики на уровень базы данных, то есть помещение их в хранимые процедуры и триггеры. Это также будет полезно для клиента. Любой может вызвать SP и быть уверенным, что данные будут сохранены в согласованном состоянии, в соответствии с вашими правилами бизнес-логики.

1 голос
/ 18 марта 2010

Я думаю, что это общая проблема и серьезная проблема, поэтому я погуглил и нашел эту статью в первую очередь.

Как насчет создания открытого статического класса для хранения всех значений поиска, но вместо жесткого кодирования мы инициализируем эти значения при загрузке приложения и используем имена для их ссылки?

В моем приложении мы попробовали это, это сработало. Также вы можете сделать некоторые проверки, например, количество различных возможных значений поиска в коде должно быть таким же, как в db, в противном случае log / email / etc. Но я не хочу вручную кодировать это для статуса 40+ бизнес-сущностей.

Кроме того, это может быть частью более серьезной проблемы сопоставления ИЛИ. У нас слишком много деталей о слое постоянства, и поэтому мы должны позаботиться об этом. С такими технологиями, как Entity Framework, нам не нужно беспокоиться о «синхронизации», потому что она автоматизирована, я прав?

Спасибо!

1 голос
/ 30 октября 2009

Не переусердствуйте. Прежде чем пытаться найти решение этой проблемы, вам нужно выяснить, если это даже проблема. Можете ли вы вспомнить какой-либо законный гипотетический сценарий, в котором вы бы изменили значения в таблице itemState? Не просто "Что если кто-то изменит эту таблицу?" но «Кто-то хочет изменить эту таблицу по-X по причине Y, какой эффект это даст?». Вам нужно оставаться реалистичным.

Новое государство? Вы добавляете строку, но она не влияет на существующие. Удаление состояния? Вы все равно должны удалить ссылки на него в коде. Изменение идентификатора состояния? Нет законных оснований для этого. Меняется название штата? Для этого нет законных оснований.

Так что действительно не должно быть причин для беспокойства по этому поводу. Но если вам нужно, чтобы это можно было легко обслуживать в случае иррациональных людей, которые случайным образом решили изменить Доступно на 2, потому что это просто лучше соответствует их фен-шую, убедитесь, что все таблицы генерируются с помощью сценария, который считывает эти значения из файла конфигурации, и затем убедитесь, что весь код читает константы из того же файла конфигурации. Затем у вас есть одно местоположение определения, и каждый раз, когда вы хотите изменить значение, вы изменяете этот файл конфигурации вместо БД / кода.

1 голос
/ 30 октября 2009

Ответ полностью зависит от языка, который вы используете: решения для этого не одинаковы в Java, PHP, Smalltalk или даже Assembler ...

Но позвольте мне сказать вам кое-что: хотя это действительно жестко закодированные значения, это не очень хорошая вещь, но бывают случаи, когда они вам нужны. И этот в значительной степени один из них: вам необходимо объявить в своем коде свои текущие знания бизнес-логики, которая включает эти жестко закодированные состояния .

Итак, в данном конкретном случае я бы жестко запрограммировал эти значения.

1 голос
/ 30 октября 2009

Вам понадобится какое-то предопределенное значение, которое никогда не изменится, будь то целое число, строка или что-то еще.

В вашем случае числовое значение состояния - это суррогат штата PRIMARY KEY, который никогда не должен изменяться в хорошо спроектированной базе данных.

Если вас беспокоит последовательность, используйте код CHAR: A, R или B.

Однако вы должны придерживаться его, а также числового кода, чтобы A всегда означало Available и т. Д.

Структура вашей базы данных должна быть документирована так же, как и код.

0 голосов
/ 23 февраля 2011

Значения должны быть жестко закодированы, что фактически означает, что они не могут быть изменены в базе данных, а это означает, что хранение их в базе данных является избыточным.

Таким образом, запрограммируйте их жестко, и в базе данных нет таблицы поиска. Вместо этого сохраняйте состояние элементов непосредственно в таблице элементов.

0 голосов
/ 30 октября 2009

Я использовал метод, аналогичный тому, что вы описываете - таблицу в базе данных со значениями и описаниями (полезно для отчетов и т. Д.) И перечислением в коде. Я обработал синхронизацию с помощью комментария в коде, говорящего что-то вроде «эти значения взяты из таблицы X в базе данных ABC», так что программист знает, что база данных должна быть обновлена. Чтобы предотвратить изменения со стороны базы данных без соответствующих изменений в коде, я установил разрешения для таблицы так, чтобы только определенные люди (которые, надеюсь, помнят, что им также нужно изменить код) имеют доступ.

...