Где вы кладете данные своего словаря? - PullRequest
4 голосов
/ 25 февраля 2009

Допустим, у меня есть набор стран в моем приложении. Я ожидаю, что эти данные изменятся, но не очень часто. Другими словами, я не рассматриваю этот набор как оперативные данные (например, я бы не стал предоставлять операции CRUD для страны).

Тем не менее, я должен где-то хранить эти данные. Я вижу два способа сделать это:

  • База данных управляется. Создайте и заполните таблицу Country. Предоставьте какой-нибудь DAO для доступа к нему (findById ()?). Таким образом, клиентский код должен знать идентификатор страны (который также может быть именем или кодом ISO). На стороне приложения у меня будет класс Country.

  • Приложение управляемо. Создайте Enum, где я могу перечислить все страны, известные моей системе. Он также будет храниться в БД, но разница будет в том, что теперь клиентскому коду не нужно иметь метод поиска (findById, findByName и т. Д.) И идентификатор жесткого кода, имена или коды ISO. Он будет ссылаться на конкретную страну напрямую.

Я склоняюсь к второму решению по нескольким причинам. Как ты это делаешь?

Правильно ли называть эти «словарные данные»?

Приложение. Одна из основных проблем заключается в том, что если у меня есть метод поиска, подобный findByName ("Чехословакия") , то после 1992 года он ничего не даст. Я не знаю, как клиентский код отреагирует на него (в конце концов, он ожидает, что всегда получит страну обратно, потому что, ну, это словарные данные). Это становится еще хуже, если у меня есть что-то вроде findById (ID_CZ) . Будет очень трудно найти все эти зависимости.

Если я исключу страну.Чехословакию из своего списка, я заставлю себя позаботиться о любой зависимости от Чехословакии.

Ответы [ 7 ]

2 голосов
/ 25 февраля 2009

В некоторых приложениях, над которыми я работал, в базе данных была единственная таблица 'Enum', которая содержала все данные этого типа. Он просто состоит из двух столбцов: EnumName и Value и будет заполняться следующим образом:

  • "Страна", "Германия"
  • "Страна", "Великобритания"
  • "Страна", "США"
  • "Фрукты", "Яблоко"
  • "Фрукт", "Банан"
  • "Фрукт", "Апельсин"

Это было прочитано и кэшировано в начале выполнения приложения. Преимущества в том, что мы не использовали десятки таблиц базы данных для каждого отдельного типа перечисления; и нам не нужно было ничего перекомпилировать, если нам нужно было изменить данные.

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

1 голос
/ 25 февраля 2009

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

Я также не стал бы пытаться создать общую таблицу enum, поскольку saw-lau предложил , главным образом потому, что вы теряете чистые ограничения внешнего ключа, что является главным преимуществом их наличия в БД в первую очередь. (мог бы хорошо воткнуть их в текстовый файл). Базы данных хороши в обработке множества таблиц. Присвойте имена таблиц "ENUM_", если вы хотите их различать.

Приложение всегда может загрузить их на карту как время запуска или при запуске события перезагрузки.

РЕДАКТИРОВАТЬ: Из комментариев " Конечно, я буду использовать ограничения внешнего ключа в моей БД. Но это может быть сделано с использованием или без использования перечислений на стороне приложения "

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

1 голос
/ 25 февраля 2009

Это вам не поможет, но зависит ...

-Что вы собираетесь делать с этими странами?

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

- Собираетесь ли вы переводить названия стран на несколько языков?

- Зависит ли бизнес-логика вашего приложения от выбранной страны? -Тебе нужен класс Country?

и т.д ...

Без дополнительной информации я бы начал с Enum с несколькими странами и рефакторингом в зависимости от моих потребностей ...

1 голос
/ 25 февраля 2009

Возможно, у меня в банке есть текстовый файл. Я бы загрузил его в память при запуске (или при первом использовании). В этот момент:

  • Легко изменить (даже если у вас нет знаний в области программирования)
  • Легко обновить даже без полного перераспределения - поместите только текстовый файл где-нибудь на пути к классам
  • Доступ к базе данных не требуется

РЕДАКТИРОВАТЬ: Хорошо, если вам нужно ссылаться на данные конкретной страны из кода, то либо:

  • Используйте подход enum, который будет всегда означать перераспределение
  • Используйте описанный выше подход, но сохраните перечисление идентификаторов стран, а затем проведите модульный тест, чтобы убедиться, что каждый идентификатор сопоставлен в текстовом файле. Это означает, что вы можете изменить оставшиеся данные без перераспределения, и нетехнический специалист может обновлять данные, не видя страшного кода везде.

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

1 голос
/ 25 февраля 2009

Лично я всегда придерживался подхода к базе данных, в основном потому, что я уже храню другую информацию в базе данных, поэтому написание другого DAO легко

Но другой подход может заключаться в том, чтобы сохранить его в файле свойств в банке? Я никогда не делал этого в Java, но, похоже, это часто встречается в разработке для iPhone (то, что я сейчас изучаю).

1 голос
/ 25 февраля 2009

Если оно не будет меняться очень часто, и вы можете позволить себе закрыть приложение для применения обновлений, я бы поместил его в перечисление Java и написал свои собственные методы для findById(), findByName() и так далее.

Преимущества:

  • Быстро - нет доступа к БД для инвариантных данных (или кеширования);
  • Simple;
  • Хорошо играет с инструментами рефакторинга.

Недостатки:

  • Нужно сбить приложение для обновления.

Если вы поместите данные в свой собственный jar-файл, обновление так же просто, как обновление jar и перезапуск приложения.

Жесткое кодирование может быть устранено потребителями, хранящими значение самого перечисления, или путем ссылки на код ISO, который вряд ли изменится для стран ...

Если вы беспокоитесь о том, чтобы сохранить это перечисление «в синхронизации» с базой данных, напишите интеграционный тест, который точно проверяет это и регулярно его запускает (например, на вашем компьютере CI).

0 голосов
/ 25 февраля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...