Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Expression<Func<T, bool>> а не Predicate<T> или Func<T, bool> что давало возможность репозиторию использовать его в фильтрах без маппингов и загрузки всей таблицы в память.а в некоторых случаях будет вредот всего может быть вред, если пренебрегать правилами использования. ( касается не только IT сферы, а всего медицины, техники… )
без всяких абстракций поддерживает работу с различными движками.
If (mode == someOne)
using ( var context = new MyDbEntitiesOne() )
{...}
else
using ( var context = new MyDbEntitiesTwo() )
{...}
а чего, нормальный функционал, за то работает.так же с абстракцией куда удобнее работать
Сама по себе сущность подписи бесполезна, она агрегируется в сообщении и отдельно ее запрашивать у хранилища с точки зрения предметной области бессмысленно (а значит хорошо бы заблокировать эту возможность)
Страшное заблуждение. Логика должна быть обратная. Насколько полезна сущность сообщения без подписей, если есть операции с сообщениями без подписей, то подписи и сообщения — разные сущности, а если нет, то одна.Сообщение может существовать без подписи ( не подписанное ), а подпись без сообщения? Существование подписи без сообщения это плохо. Исходя из операций которые можно совершать над подписью -> проверить ее подлинность, без содержимого исходного сообщения это не возможно. Сообщение агрегирует в себе подпись и ни как иначе. Что касается
Я описал чем Объекты предметной области могут отличаться от объектов хранилища, а так же отсеиваются заведомо бесполезные операции
Существование подписи без сообщения это плохо
Исходя из операций которые можно совершать над подписью -> проверить ее подлинность, без содержимого исходного сообщения это не возможно.
Сообщение агрегирует в себе подпись и ни как иначе.
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.Так в чем я не прав, это слой между предметкой и хранилищем ( либо как говориться у Фоулера слоем отображения данных ). Так в чем я не прав то?
ждый для себя сам решает — нужна ли ему абстракция повверх технологии хранения данных или нет.. Вообще любое приложение может быть написано без какого либо проектирования и оно будет работать, до тех пор пока не изменяться требования к системе или не придётся менять технологии, а уже от этого любой более менее рыночный продукт не то что не застрахован, а наоборот этот этап его настигнет, и дальнейшее существование будет завесить от того на сколько он адаптируемый под новые задачи. Разделение слоев и выделение доменного слоя это очень мощная и гибкая система, хотя и очень при очень затратная по ресурсам.
польза от абстракций без дополнительного функционала
При нашем подходе замена хранилища не составит труда, но его менять не зачем.
.NET использует интерпретатор для исполнения программ, что так же замедляет, причем сильно.
Но есть 1 ОГРОМНЫЙ -минус — это надо делать самому.
Интерпретируемые языки программирования отличаются тем, что исходники не преобразовываются в машинный код для непосредственного выполнения на ЦПУ, а исполняются с помощью специальной программы-интерпретатора.
Как промежуточный вариант, многие языки (Java, C#, Python) транслируются в машинно-независимый байт-код,
который все еще не может быть исполнен напрямую на ЦПУ, и чтобы его исполнить все еще необходим интерпретатор.
Почему интерпретация медленней? Ответ на этот вопрос, как ни странно не всем кажется очевидным, хотя он действительно очень простой: интерпретируя каждую команду по отдельности, мы затрачиваем дополнительные ресурсы на перевод семантики этой команды на язык процессора. Кроме того современные процессоры оптимизированы для выполнения последовательных команд (см. Конвейер), а интерпретатор чаще всего представляет собой огромный switch с кучей опций, загоняющий в тупик предсказатель переходов.
А ваш репозиторий с преобразованием доменных запросов в специфичные для хранилища и обратно — не надо?Конечно надо, но это не самое страшное, больше всего времени затрачивает маппинг.
и вообще на поддержание полудесятка введенных абстрактных слоев, практический смысл которых ускользает.есть несколько вопросов, на которые отвечают эти абстракции
какова должна быть структура Query Object?
как представлять произвольный фильтр в Query Object?
как ссылаться на свойства объектов в Query Object?
как отображать пейджинг и сортировку в Query Object?
зависит только от предметной области
произвольный фильтр это зло
расшифруйте, я не понял
Значит, репозиторий не отвечает на этот вопрос, он просто сдвигает его в предметную область. QED.Передав запрос в терминах предметной области в репозиторий, который итерпритирует его и возвращает то, что требуется в запросе.
Расскажите это пользователю (настоящему реальному пользователю вашей программы), который хочет выбирать данные по заказчикам, отфильтрованные по произвольному критерию поверх 18 признаков.а почему все эти 18 критериев не описать в объекте запроса?
«как сослаться на свойство „возраст“ класса „сотрудник“»?конкретный репозиторий возвращает определенный тип объектов, запросы для получения этих объектов нужно формировать запросы, по которым реп разберет что от него хотят. Проблемы в упор не вижу.
Передав запрос в терминах предметной области в репозиторий, который итерпритирует его и возвращает то, что требуется в запросе.
IQueryable.а почему все эти 18 критериев не описать в объекте запроса?
конкретный репозиторий возвращает определенный тип объектов, запросы для получения этих объектов нужно формировать запросы, по которым реп разберет что от него хотят. Проблемы в упор не вижу.
Вы только что описали работу IQueryable.нет, я описал ее идею.
Количество кода себе представляете?
который не является неотъемлемой частью Repository и прекрасно реализуется на других уровнях).как сказать.
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.действительно про запросы ни где не сказано, но использовать чистый Repository, как и любую абстракцию сложно, одно ясно что запрос должен идти в терминах предметной области и передаваться репозиторию, для этого можно использовать QueryObject или другой подход, но то что реп должен умет все это переводить в запросы хранилища и именно он должен это делать.
не на много больше чем все эти критерии засунуть в LINQ
как сказать.
модель должна соответствовать бизнесу, а хранилище — чему-нибудь.я говорю что они могут сильно отличаться
1) Сделать набор сервисов (как для внешних, только без передачи по сети), которые выставляют функции и отдают\получают данные (не объекты).
2) Научить их работать с моделью, зашив проверку инвариантов при сохранении (DbContext.SaveChanges).а зачем дожидаться этого самого сохранения, ведь инварианты можно проверить и раньше CodeContracts research.microsoft.com/en-us/projects/contracts проверка инвариантов это уровень домена, но как правило это забывают и не используют, тк «Да этж сколько писать? в два раза больше кода.....».
а зачем дожидаться этого самого сохранения, ведь инварианты можно проверить и раньше CodeContracts
Во-первых, не все инварианты легко выражаются в Code Contracts.согласен
Во-вторых, вы проверку инвариантов будете делать на каждой операции, модифицирующей состояние объекта?по хорошему бы да, но это затратно ( хотя если просто проверять поля или свойства с простыми проверками, то это быстро )
Проверка на сохранении гарантирует, что невалидный объект не попадет в хранилище, это весьма сильная гарантия.согласен, но как правило невалидный объект попадает в хранилище тк невалидным является объект предметной области и можно проверять его, хотя тут большой вопрос искажения объекта может быть во время маппинга, но тогда проверка объекта предметки не поможет, я наверное параноик нужно проверять и предметную область и то что может попасть в хранилище, сразу будет видно откуда у проблемы растут ноги.
как правило невалидный объект попадает в хранилище тк невалидным является объект предметной области и можно проверять его
программист вообще может работать с БД напрямую из другой программытут уже ни какие проверки не помогут, только
Параноики еще и в самом хранилище делают проверки.ну то есть паранойя оправдана?
ну то есть паранойя оправдана?
Есть одна замечательная вещь, без которой многопользовательская работа ( корректная ) не возможна блокировки.
Предоставлять одновременное редактирование одних и тех же данных — сумасшествие.
Во-вторых, вы проверку инвариантов будете делать на каждой операции, модифицирующей состояние объекта?
по хорошему бы да, но это затратно
но разве репозиторий этого не делает? он возвращает объекты предметной модели (области, слоя, как не назови)
а зачем дожидаться этого самого сохранения, ведь инварианты можно проверить и раньше CodeContractsВы не знаете о чем говорите. Когда у вас данные вводятся пользователям, то проверить стаически почти невозможно. Более того, как проверить инвариант вроде «у менеджера должно быть не более 10 подчиненных». Сразу учитывайте, что пользователи будут конкурентно добавять и удалять связанные элементы, а ваш код будет работать более чем на одном компьютере.
Какой смысл ограничивать выборки — я не понимаю.простой, по проекту в 25 местах делаются общие выборки по каким либо критериям, настал момент и уже те же самые запросы должны осуществляться с еще парой параметров. и что? лезть по всему проекту искать где и кто делает такие выборки? Запросы должны быт четко сформулированы в терминах предметной области
А какая разница в чем сформулированы запросы, если все равно надо искать и править?Вот у нас есть User вот у нас запрос в терминах предметной области query.AvaibleUsers, отлично avaible определяется заблокирован пользователь или нет, через какое то время вводиться еще одно свойство Baned, и теперь доступность определяется не заблокирован и не забанен, обратите внимание что запрос как был так и остался, измениось только его исполнение.
Вы не знаете о чем говорите. Когда у вас данные вводятся пользователям, то проверить статически почти невозможно.вариантов может быть много, согласен что не все они могут сразу быть проверены, но те которые могут, лучше всего проверять не отходя далеко, в момент подтверждения действий пользователя
А если возникает конкурентный доступ с нескольких серверов к одним и тем же данным?а вот тут забавная ситуация, сидел пользователь пол часа правил, пытается сохранить, опаньки кто то до него внес изменения и сохранил, и мы рушим его работу, эх
lock escalationа где я про это писал?
приходит клиент, выбирает место, кассир блокирует место, поле оплаты подтверждается продажа, билет продан блокировка снята.
а где я про это писал?
А что делать, если после того, как клиент выбрал место (и оно заблокировано), клиент отвалился?удалит запись о блокировке из таблицы.
Но это никак не отменяет существования этой проблемы.почитайте внимательно, то о чем я пишу, такой проблемы не будет.
удалит запись о блокировке из таблицы.
почитайте внимательно, то о чем я пишу, такой проблемы не будет.
4.Нажали «купить»блокировка
6.Оплатилисохранили, сняли блокировку
Почему не будет?в таблице блокировок уникальность записи по составному ключу. lock escalation там не нужен, возможно вы не правильно поняли, таблица блокировок это НАШЕ творение.
Нажали «купить»блокировка
Оплатили
сохранили, сняли блокировку
в таблице блокировок уникальность записи по составному ключу. lock escalation там не нужен, возможно вы не правильно поняли, таблица блокировок это НАШЕ творение.
Прекрасно. А если к этому моменту другой пользователь нажал «купить» с теми же местами?одновременно внести записи в таблицу с одинаковыми ключами не возможно.
(а) что делать, если пользователь не оплатил?я ж писал, дата (таймаут) по которой блокировка считается не действительной
(б) как в дальнейшем не продать билеты на эти места?при сохранении отмечаем что билет продан.
Это обычная таблица в SQL, или что-то другое? Если да, то как, по-вашему, БД обеспечивает уникальность записей в индексе?да,
ALTER TABLE [dbo].[Table] ADD CONSTRAINT [DF_Table_number] DEFAULT ((0)) FOR [number]
уникальность, правда это не ключ, просто вариантов несколько, как унифицировать записьодновременно внести записи в таблицу с одинаковыми ключами не возможно.
я ж писал, дата (таймаут) по которой блокировка считается не действительной
при сохранении отмечаем что билет продан.
да, ALTER TABLE [dbo].[Table] ADD CONSTRAINT [DF_Table_number] DEFAULT ((0)) FOR [number] уникальность, правда это не ключ, просто вариантов несколько, как унифицировать запись
UNIQUE CONSTRAINT, то мой вопрос остается актуальным: как, по-вашему, БД гарантирует уникальность? (кстати, в случае с констрейнтом будет хуже, чем в случае с индексом)И что произойдет с точки зрения пользователя?инфа о том что билет продан
И кто/как эту дату обрабатывает?1. проверка есть ли блокировка
Отмечаем где?хороший вопрос, ну мы же где то должны сохранить, что такие то билеты проданы.
Вообще-то, это не уникальность, а дефолтное значение.да, не оттуда копипаст, промазал
как, по-вашему, БД гарантирует уникальность?видимо блокирует таблицу на время записи.
инфа о том что билет продан
1. проверка есть ли блокировка
2. если нет, то ставиться блокировка и устанавливается тайм
3. если есть, то проверяется таймаут, если он просрочен, то сносим блокировку, переход к 2
видимо блокирует таблицу на время записи.
Ну то есть пользователь выбрал билет, нажал кнопку, а ему и говорят: билет продан? Прекрасно, в чем тогда вообще смысл этого упражнения с «блокировками»?в том что он это узнает сразу, а не после того как он ввел все данные и подтвердил
«как же показать пользователю карту незанятых мест?»свободные места — не проданные билеты + на которых нет действительных блокировок
Правда, печально?да я то же понял что вы описали именно эту проблему, но смотря в глаза реальности скорость продажи билетов не космическая.
в том что он это узнает сразу, а не после того как он ввел все данные и подтвердил
свободные места — не проданные билеты + на которых нет действительных блокировок
да я то же понял что вы описали именно эту проблему
да я то же понял что вы описали именно эту проблему, но смотря в глаза реальности скорость продажи билетов не космическая.
Параноики еще и в самом хранилище делают проверки.)
Получается все рассуждения про domain model ничего не стоятсервис будет входить в DM
Вполне может быть, что будет два инстанса сервиса (а в реальности — будет обязательно, для отказоустойчивости).если на 1 машине, то mutex, а вот если на нескольких, то в сеж бд
Агенты без хранения состояния, как можно меньшая область необходимой консистентности, оптимистичные сценарии обработки конкуренции, готовность к откату.это тривиально?
готовность к откату.а разве это не учитывается процессом?
все таки решить поставленную задачу можно только с помощью не тривиальной реализации бизнес — процессов.наверное так будет лучше.
кстати эта особенность возможно только благодаря абстракцииЭта абстракция уже есть в ORM, вам не нужно свою городить поверх.
И то что объект домена может сильно отличаться от объекта хранилища, а так же с абстракцией куда удобнее работать и еще много всяких плюсов при работе с Repository и UoW, толкают на реализацию своего DAL в приложении.Мне кажется вы сами себе выдумываете проблему и пытаетесь её решать. Я вот не увидел в этом посте или комментах удобства и «плюсов» от Repository и UoW. Также не очень понятно в чем проблема, что «объект домена» отличается от объекта хранилища. Домен — операции, хранилище — данные, они должны отличаться.
Эта абстракция уже есть в ORM, вам не нужно свою городить поверхнужно написать ее конкретную реализацию
Я вот не увидел в этом посте или комментах удобства и «плюсов» от Repository и UoW.так ведь пост изначально был про Specification.
Есть система сообщений, каждое сообщение подтверждается подписью (ЭЦП), ...
нужно написать ее конкретную реализацию
так ведь пост изначально был про Specification.
Не нужно, реализации тоже естьдумаю что не для всего ( но для самого распространённого )
Это не ответ на вопрос в чем плюсы от repository и uow.так и есть, но для раскрытия данной темы нужно писать отдельный пост ( обещаю написать раз такое дело ).
К сожалению не всегда можно описать сущность хранилища что бы она отражала суть предметной области.
Data Access Layer в .net уже года три как полностью закрывается EF. Больше ничего писать не нужно. Более того, любой дополнительный код скорее вреден.
Data Access Layer в .net уже года три как полностью закрывается EF. Больше ничего писать не нужно.
Прогноз на Specification pattern в Domain layer — ожидаются проблемы