Вот тут возник интересный вопрос по QueryObject — это все же область BLL или DAL.
По сути, сам QueryObject это выражение некоего требования BLL к DAL ("дай мне объекты X по условию Y").
Вот предположим у нас в проекте все BLL Models мапятся в БД как есть. В этом случае QueryObject содержит linq запрос в терминах решаемой задачи. Вроде получается QueryObject принадлежит к BLL.
Теперь прдставим, что DAL (по каким-то причинам) вводит свои DTO и мапит в них BLL Models перед сохранением. Выходит, что в QueryObject должны уже быть linq запросы, где требования бизнес-логики выражены в объектах DAL DTO. Тогда это DAL или BLL?
PS: Что-то мне подсказывает что это будет Infrastructure, т.к. по сути посредник между БД и приложением. В общем, что-то путаться начинаю. Подскажите как правильно.
PPS: Размышляя далее начинаю приходить к выводу что все же паттерн Repository более универсален, по сравнению с QueryObject. Главное правильно его (Repository) готовить.
Здравствуйте, Doc, Вы писали:
IT>>DAL и BL при использовании Linq — это анахронизм, пережитки прошлого, от которых нужно избавлятся. Doc>Про DAL можно спорить, но почему BL анахронизм??? Где тогда бизнес логика?
А что такое бизнес логика? По-моему, бизнес логика — это отъём данных у формы ввода, валидация этих данных, первичная обработка, вторичная обработка, третичная валидация, сохранение в БД. Либо же отбор параметров у запроса, валидация параметров, запрос данных из БД, часто включающий в зависимости от бизнес логики различные фильтрации, группировки и сортировки на уровне SQL, рендеринг полученных данных в HTML или отображение на UI. В большинстве такой бизнес логике BL участвует лишь своими path through методами для переброски данных от БД к потребителю. И таких методов в BL 80%. Ну и нафига такую логику выделять в отдельный слой? Кроме как для внесения дополнительных проблем в понимание такого кода и его поддержку лично я никаких других преимуществ в нём больше не вижу.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Doc, Вы писали:
Doc>Про DAL можно спорить, но почему BL анахронизм??? Где тогда бизнес логика?
Игорь имеет в виду, что бизнес-логика конечно выносится в отдельные классы и методы, просто он не называет это слоем, а называет набор этих классов модулями или сервисами.
Здравствуйте, MozgC, Вы писали:
MC>Игорь имеет в виду, что бизнес-логика конечно выносится в отдельные классы и методы, просто он не называет это слоем, а называет набор этих классов модулями или сервисами.
Да я даже не знаю что ответить на его сообщение. Поскольку там сказано что BL занимается сохранением данных в БД и рендерингом HTML.
По-моему, бизнес логика — это отъём данных у формы ввода, валидация этих данных, первичная обработка, вторичная обработка, третичная валидация, сохранение в БД. Либо же отбор параметров у запроса, валидация параметров, запрос данных из БД, часто включающий в зависимости от бизнес логики различные фильтрации, группировки и сортировки на уровне SQL, рендеринг полученных данных в HTML или отображение на UI.
Но даже если все как вы сказали, то получается демагогия. Ну называйте это модулем — ключевой смысл то от этого не изменится. Главное, что это особобленная часть кода, служащая определенной цели.
А спорить про tier, layer, модуль итд можно бесконечно. Например, лично я не вижу проблем, чтобы в некоторых проектах в одной сборке лежали несколько слоев (layers).
Здравствуйте, Doc, Вы писали:
Doc>Вот тут возник интересный вопрос по QueryObject — это все же область BLL или DAL.
Doc>По сути, сам QueryObject это выражение некоего требования BLL к DAL ("дай мне объекты X по условию Y").
Doc>Вот предположим у нас в проекте все BLL Models мапятся в БД как есть. В этом случае QueryObject содержит linq запрос в терминах решаемой задачи. Вроде получается QueryObject принадлежит к BLL.
Doc>Теперь прдставим, что DAL (по каким-то причинам) вводит свои DTO и мапит в них BLL Models перед сохранением. Выходит, что в QueryObject должны уже быть linq запросы, где требования бизнес-логики выражены в объектах DAL DTO. Тогда это DAL или BLL?
Doc>PS: Что-то мне подсказывает что это будет Infrastructure, т.к. по сути посредник между БД и приложением. В общем, что-то путаться начинаю. Подскажите как правильно.
Doc>PPS: Размышляя далее начинаю приходить к выводу что все же паттерн Repository более универсален, по сравнению с QueryObject. Главное правильно его (Repository) готовить.
У вас фаулеризм головного мозга. Надо срочно сжечь книги по архитектуре и DDD и читать SICP.
Здравствуйте, Doc, Вы писали:
Doc>Здравствуйте, gandjustas, Вы писали:
G>>У вас фаулеризм головного мозга. Надо срочно сжечь книги по архитектуре и DDD
Doc>Ага, так я и кинулся планшет жечь
С планшета можно просто удалить.
G>>и читать SICP.
Doc>И тогда какая болезнь будет?
Скобочный рак, но эта болезнь протекает легче и не ведет к повреждению мозга.
А если серьезно, то стоит внимательнее почитать фаулера. У него черным по-английскому написано, что Repository это объекты, который отдает DTO в обмен на QueryObject. Это все уже давно реализовано в ORM и IQueryable интерфейсе. И нет смысла прятать что-то куда-то. PL и BL формируют QueryObject (который IQueryable) для своих нужд и вызывают DAL (который repository, который ORM) чтобы получить конкретные объекты или внести изменения.
Это уже получается функциональная декомпозиция, о которой очень подробно написано в SICP.
Здравствуйте, gandjustas, Вы писали:
G> Это все уже давно реализовано в ORM и IQueryable интерфейсе.
В принципе согласен.
Но вот на практике не все так гладко. Например, есть проблема в том, что в сами запросы иногда норовят влезть (причины разыные) детали реализации ORM/СУБД. Таким образом QO становится связанным с ними. И тогда вся эта пляска с абстракциями/ORM/Repository итд выглядит бессмысленно. Все равно прикручены к (например) MSSQL/EF.
Пример — на "стандартном" linq не выйдет написать запрос c поиском по шаблону. Или у меня были запросы, которые работали на MSSQL но падали на MySQL (а надо было общаться и с той и с той БД). Да, баг mySQL, да поправят, но сроки то идут и в своем коде делаешь костыль для запроса.
Далее — ограничения ORM. Тот же EF не умеет делать update/delete пачками. А грузить даже 1000 сущностей только ради их удаления еще то удовольствие (по времени). А индексы создать для CodeFirst (холиварить не надо )? Поэтому у меня в итоге остается DAL, который является декоратором для ORM.
Здравствуйте, Doc, Вы писали:
Z>>А когда QueryObject захочется спрятать, что делать будешь?
Doc>А когда перестанишь другим свои мысли присваивать, что писать на форуме будешь?
Намек, очевидно, не понят. LINQ и есть замечательная реализация паттерна QueryObject.
Здравствуйте, IT, Вы писали:
IT>А что такое бизнес логика? По-моему, бизнес логика — это отъём данных у формы ввода .... И таких методов в BL 80%.
Не, это нифига не бизнес-логика, это инфраструктурный код смешанный с логикой поведения приложения. Первое должно быть спрятано за хелперами и переезжать из проекта в проект, второе — писаться по сценариям для UI (если они есть конечно).
Бизнес-логика — это то, что имеет непосредственное отношение к описанию деятельности заказчика. Например, логика принятия заказов для разных категорий клиентов (если она есть конечно), выдача оборотки, анализ затрат-запасов, мониторинг индикаторов и т.д. и т.п.
IT> Ну и нафига такую логику выделять в отдельный слой? Кроме как для внесения дополнительных проблем в понимание такого кода и его поддержку лично я никаких других преимуществ в нём больше не вижу.
+1
Здравствуйте, Doc, Вы писали:
Doc>Здравствуйте, gandjustas, Вы писали:
G>> Это все уже давно реализовано в ORM и IQueryable интерфейсе.
Doc>В принципе согласен.
Doc>Но вот на практике не все так гладко. Например, есть проблема в том, что в сами запросы иногда норовят влезть (причины разыные) детали реализации ORM/СУБД. Таким образом QO становится связанным с ними. И тогда вся эта пляска с абстракциями/ORM/Repository итд выглядит бессмысленно. Все равно прикручены к (например) MSSQL/EF.
А оно и есть бессмысленно, этим не надо заниматься.
Doc>Пример — на "стандартном" linq не выйдет написать запрос c поиском по шаблону. Или у меня были запросы, которые работали на MSSQL но падали на MySQL (а надо было общаться и с той и с той БД). Да, баг mySQL, да поправят, но сроки то идут и в своем коде делаешь костыль для запроса.
Костыли инкапсулируешь в классы, создаешь реализации для разных баз и используешь IoC.
В итоге будет что-то вроде:
Doc>Далее — ограничения ORM. Тот же EF не умеет делать update/delete пачками.
Если очень надо и критично, то используй BLToolkit, если нет, то можно и загрузить\обновить.
Doc>А грузить даже 1000 сущностей только ради их удаления еще то удовольствие (по времени).
Их грузить не обязательно, достаточно ключи иметь.
На крайняк можно просто sql запрос в хранилище отдать. Не напрямую, а примерно как в коде выше.
Doc>А индексы создать для CodeFirst (холиварить не надо )? Здесь нету того что нужно?
Здравствуйте, gandjustas, Вы писали:
G>Костыли инкапсулируешь в классы, создаешь реализации для разных баз и используешь IoC.
Ну собственно вот и вынос QO (части их) в отдельную сборку. G>Их грузить не обязательно, достаточно ключи иметь.
Часто встречали ситуацию, когда 1000 ключей известно. Как правило нужен аналог delete from t where ...
Doc>>А индексы создать для CodeFirst (холиварить не надо )? G>Здесь нету того что нужно?
Есть. Но хоть migration, хоть велосипед — вопрос в том, что IMHO самый что не наесть DAL.
Но мы сейчас скатились к разговору нужен DAL или нет. Это не суть исходного вопроса. Давайте вернемся к тому, с чего я начинал. Мы не можем (по какой-то не важной тут причине) замапить наши Models напрямую в БД. Появляются DTO объекты, в которые сохраняются Models. Где расположим эти объекты. И самое главное, что тогда linq запросы должны оперировать и Models и DTO. Выходит они должны быть в с BLL.
И даже если исключить DAL, то получается что OQ должны располагаться в Infrastructure (то что у меня вышло, походит на описание Hexagon и Onion Architecture).
Здравствуйте, Doc, Вы писали:
Doc>Да я даже не знаю что ответить на его сообщение. Поскольку там сказано что BL занимается сохранением данных в БД и рендерингом HTML.
Видимо ты под BL понимаешь исключительно слой бизнес логики. Я же говорил просто о логике работы приложения.
Doc>Но даже если все как вы сказали, то получается демагогия. Ну называйте это модулем — ключевой смысл то от этого не изменится. Главное, что это особобленная часть кода, служащая определенной цели.
Ну тогда почитай определение abstraction layer, хотя бы здесь.
Doc>А спорить про tier, layer, модуль итд можно бесконечно. Например, лично я не вижу проблем, чтобы в некоторых проектах в одной сборке лежали несколько слоев (layers).
Сборка — это дело десятое. Предназначение слоя — это изоляция и скрытие деталей имплементации. Это хорошо работало в случае DAL, т.к. его основное предназначение — изоляция приложения от работы с прямым SQL. Linq эту проблему устраняет на корню, поэтому в DAL надобность отпадает. BLL в подавляющем большинстве случаев используется просто за компанию и в своей основе состоит из тупой переброски вызовов от потребителя к DAL. Смысла в этих методах ровно 0, только вред. А всё что остаётся от BLL без них можно оформить ввиде небольших сервисных модулей.
Если нам не помогут, то мы тоже никого не пощадим.