Распространение бизнес-логики между БД и клиентом - PullRequest
1 голос
/ 15 марта 2012

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

Еще одно требование - уникальность аккаунта.Поэтому я не могу добавить два одинаковых аккаунта.Мой вопрос заключается в том, должен ли я проверить существование этой учетной записи на клиенте (сделать какой-либо запрос и посмотреть на результат) или создать хранимую процедуру для добавления новой учетной записи и проверить наличие учетной записи там.Что касается меня, то лучше сделать только сохраненный процесс, там я могу сделать любые необходимые проверки и после всех проверок добавить новую учетную запись.Но есть плюсы и минусы этого пути.Например, будет очень трудно управлять множеством сообщений, которые должен выдавать хранимый proc.


POST EDIT

У меня уже есть какие-либо ограничения базы данных и т. Д.Проблема заключается в том, как обрабатывать ситуацию, когда пользователь добавляет учетную запись существования.


РЕДАКТИРОВАНИЕ ПОСТА 2

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

Итак, как мне справиться с этим недоразумением?

Я считаю, что мой вопрос является базовым и имеет проверенное решение.Мои инструменты - C #, .NET Framework 2.0.Заранее спасибо, ребята!

Ответы [ 5 ]

1 голос
/ 17 марта 2012

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

Существует возможность, конечно, предварительно проверить и затем перепроверить (предварительно на уровне приложения, повторно в БД), но, конечно, это даст дополнительный трафик БД, поэтому зависит от того, является ли это проблемой для вас.

Когда я пишу SPROC, которые будут возвращаться в приложение, я всегда использую одну и ту же структуру - я включаю параметры для кода возврата и сообщения и всегда заполняю их.Затем я могу использовать стандартные процедуры для их вызова и даже автоматически добавлять параметры.Затем я могу либо отобразить сообщение непосредственно при ошибке, либо использовать код возврата, чтобы локализовать его по мере необходимости (или автоматизировать ответ).Я знаю, что некоторые БД (например, SQL Svr) будут возвращать параметры Return_Code, но я использую свои собственные, чтобы оставить встроенные для серьезных системных ошибок и неожиданных сбоев.Также позволяет мне иметь собственные системы нумерации для кодов возврата (то есть группировать их в соответствии с перечислениями в коде и / или группировать по серьезности)

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

// Правка - Добавить:

Хороший вопрос.Но уникальность аккаунта - это очень маленький простой пример.А как насчет более сложных требований к учетным записям в бизнес-логике?Например, если я реализую только в клиентском коде (в приложении winforms), у меня все будет хорошо, но если я хочу, чтобы другой (скажем, консольная версия моего приложения или веб-сайт) вида моего приложения работал с этими учетными записями, я должен сделать все этологика снова в новом приложении!Итак, я ищу какой-то метод для хранения данных с двух сторон (серверная база данных и клиентская сторона).- kseen вчера

Если требование mutiuse всегда, то лучше его отделить.Помещение его в отдельный проект библиотеки классов позволяет использовать DLL-библиотеку вашей WinForm, консольной программой, службой и т. Д. Хотя я бы все же предпочел валидацию (уровень БД), так как это наиболее близкий момент времени к любому действию и минимумскорее всего, gazzumped.

Обычный способ - разделить на три проекта.Слой отображения [DL] (ваш winform-проект / консоль / служба / и т. Д.) И уровень бизнес-приложений [BAL] (который содержит все бизнес-правила и обращения к DAL - он ничего не знает ни о среде diplay, ни о технологии базы данных)и, наконец, уровень доступа к данным [DAL] (здесь есть все вызовы базы данных - он может быть очень простым с методом вставки / обновления / выбора / удаления на уровне SQL и SPROC и, возможно, с некоторыми классами для передачи данных туда и обратно).DL ссылается только на BAL, который ссылается на DAL.DAL может быть заменен для каждой технологии (скажем, изменение с SQL Server на MySQL), не затрагивая остальную часть приложения, и бизнес-правила могут быть изменены и установлены в BAL без влияния на DAL (DL может быть затронут, если новые методыдобавлено или отображено изменение требований из-за изменения данных и т. д.).Затем этот фреймворк можно использовать снова и снова во всех ваших приложениях, и в него легко внести довольно радикальные изменения (например, топология БД).

0 голосов
/ 15 марта 2012

Поскольку вы не должны зависеть от конкретного провайдера хранения (БД [mysql, mssql, ...], плоский файл, xml, двоичный файл, облако, ...) в профессиональном проекте, все ограничения должны проверяться в бизнесе логика (модель).

Модель не должна ничего знать о провайдере хранения.

Дядя Боб сказал что-то об архитектуре и базах данных: http://blog.8thlight.com/uncle-bob/2011/11/22/Clean-Architecture.html

0 голосов
/ 15 марта 2012

я думаю, что ответ - как и многие - "это зависит"

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

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

Я думаю, как минимум, это должно произойти.

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

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

0 голосов
/ 15 марта 2012

Решение скорее методическое, чем техническое:

  • Реализация - «Защитное программирование» и «Проектирование по контракту»
  • Если шансы на изменение бизнес-правилас течением времени очень меньше, затем примените ограничение на уровне базы данных
  • Создайте «уровень проверки или правила и уровень агрегации (или класс)», который будет управлять такими условиями / ограничениями для объекта и / или конкретного свойства
  • Гораздо более разумным способом сделать это было бы создание пользовательского элемента управления для сущности и / или конкретного свойства (в вашем случае «Код учетной записи»), который бы внутренне использовал «проверку или правила и агрегацию».layer (или class) "* ​​1010 *
  • Это позволит вам обеспечить" систематический путь развития "или более" масштабируемую и поддерживаемую "архитектуру приложения
  • Если ваше приложение являетсявеб-сайт затем, наряду с размещением проверки на стороне клиента, всегда лучше проводить проверку даже в коде бизнес-уровня или в C #
  • Когдакогда бы проверка ни провалилась, вы можете реализовать и использовать библиотеку «custom-error-message», чтобы обеспечить стандартное содержание сообщения в приложении
  • Если ошибки возникают из самой базы данных (то есть из хранимойпроцедуры), вы можете использовать тот же класс «custom-error-message» для преобразования исключения SQL в фиксированный или стандартизированный формат сообщения

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

Надеюсь, это поможет.

0 голосов
/ 15 марта 2012

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

У меня был бы класс AccountsRepository (например) с методом AddAcount, который выполнял вставку / вызывал хранимую процедуру. Используя ограничения базы данных (как упоминал HaLaBi), при попытке вставить дубликат не получится. Затем вы должны определить, как решить эту проблему (передать сообщение обратно в пользовательский интерфейс, который он не может добавить) в коде. Это позволит вам поставить тесты вокруг всего этого. Единственное изменение, которое вы внесли в базу данных, это добавление ограничения.

Только мои 2 цента утром в четверг (перед моей чашкой зеленого чая). :)

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