Разрешаете ли вы веб-уровню прямой доступ к DAL? - PullRequest
17 голосов
/ 28 апреля 2009

Меня интересует воспринимаемая «лучшая практика», закаленная здесь небольшой дозой реальности.

В веб-приложении вы разрешаете своему веб-уровню прямой доступ к DAL или он должен сначала пройти BLL?

Я говорю конкретно о сценариях, в которых действительно не задействована «бизнес-логика» - например, простой запрос: «Получить всех клиентов с фамилией« Atwood »». Сценарии, где есть какая-то логика, обязательно пройдут через BLL, поэтому давайте назовем это moo .

Хотя вы могли бы инкапсулировать этот метод внутри объекта BLL, кажется несколько бессмысленным, когда часто подпись будет точно такой же, как у объекта DLL, а код, вероятно, так же прост, как один лайнер делегировал запрос в DLL.

Если вы выберете первое - использование объекта BLL - как вы будете называть эти объекты? (Предполагая, что они делают немного больше, чем обеспечивают уровень запросов в DLL). Помощники? QueryProviders?

Мысли, пожалуйста.

Привет

Marty

Ответы [ 7 ]

34 голосов
/ 28 апреля 2009

Я не согласен с большинством сообщений здесь.

Я называю свой слой данных на веб-уровне. Если между уровнем WEB / UI ничего нет, нет смысла создавать слой «на всякий случай». Это предварительная оптимизация. Это пустая трата. Я не могу вспомнить время, когда бизнес-уровень «спас меня». Все, что он сделал, было создано больше работы, дублирования и более высокий уровень обслуживания. Я потратил годы на подписку на бизнес-уровень -> уровень данных, передавая объекты между уровнями. Я всегда чувствовал себя грязным, создавая методы, которые ничего не делали.

После того, как Эрик Эванс познакомил его с Domain Driven Design , я делаю то, что имеет смысл. Если между пользовательским интерфейсом и уровнем данных ничего нет, я вызываю уровень данных в пользовательском интерфейсе.

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

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

У меня есть два проекта: основной проект (сущности, бизнес-логика и уровень данных) и проекты пользовательского интерфейса (веб, веб-сервисы и т. Д.)

Для получения дополнительной информации я рекомендую посмотреть на этих парней:

5 голосов
/ 28 апреля 2009

По моему мнению, вы должны ВСЕГДА использовать BLL ( Уровень бизнес-логики ) между вашим веб-уровнем и вашим DAL ( Уровень доступа к данным ).

Я ценю, что для некоторых более «простых» запросов BLL будет близко имитировать DAL (например, «Выбрать все страны», «Выбрать все типы продуктов» и т. Д.), Но, честно говоря, даже в вашем примере:

(Получить всех клиентов с фамилией 'Atwood')

здесь выражается «бизнес-логика» - желание фильтровать записи данных по фамилии, если ничего больше!

Благодаря внедрению BLL с самого начала проекта становится невероятно легко вставить либо валидацию, либо дополнительную «логику», когда и когда это может понадобиться (а если ваш проект является коммерческим приложением, эта потребность будет почти конечно возникнет в конце концов, если его нет в начале проекта). Добавление в дополнительную логику, такую ​​как:

Получить всех клиентов, которые потратили более $ 10000 в этом году

или

Не разрешать клиентам с фамилией 'Atwood' для покупки товаров на сумму более 1000 * 1026 долларов

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

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

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

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

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

В целом, я не могу думать о том, чтобы НЕ включать слой BLL между моим DAL и моим веб-уровнем.

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

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

Конечно, это предполагает, что вы делаете все это "вручную". При желании вы можете значительно упростить слои DAL / BLL / UI, используя ORM , которых много! (т. е. LINQ-to-SQL / Entities , SubSonic , NHibernate и т. д.)

2 голосов
/ 28 апреля 2009

Вам нужно различать объекты BLL (какого черта они вообще? Доменные объекты?) И Сервисы. Ваши доменные объекты не должны иметь ничего общего с вашим уровнем доступа к данным. Что касается веб-уровня, он может обрабатывать ваши репозитории (например, IRepository) так же, как и любой другой сервис, который он может свободно использовать.

Итак, суть в том, что: да, веб-уровень может использовать DAL напрямую, если он инкапсулирован в свойство и представлен как стандартная служба Service Layer.

1 голос
/ 28 апреля 2009

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

1 голос
/ 28 апреля 2009

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

Что касается именования, у меня есть мой основной объект, скажем NameChange, затем у меня будет объект BLL, который является человеком, который принимает объект изменения имени, тогда у меня будет объект DAL / Entity, называемый Person. Объект Business Person находится в пространстве имен BLL, а объект DAL / Entity Person находится в пространстве имен БД (я бы выбрал DAL, если бы изначально его построил).

0 голосов
/ 28 апреля 2009

Хотя можно было бы перейти непосредственно от уровня представления к DAL, вы пропускаете список BLL, который часто требует аутентификации ...

0 голосов
/ 28 апреля 2009

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

По существу:

Пользовательский интерфейс -> BusFacade -> BusinessLogic -> DalFacade -> DataAccessLayer

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

BusFacade.GetCmsSiteMap()
BusFacade.GetProductGroup()

etc.etc.

...