Про путаницу с репозиториями и DAO
От: another_coder Россия  
Дата: 13.06.16 14:55
Оценка: +1
Удивляют люди, которые считают, что правильный репозиторий должен выголядить как этот интерфейс
    interface IRepository<T> where T : class
    {
        List<T> GetAll();
        T Find(int entityId);
        T SaveOrUpdate(T entity);
        T Add(T entity);
        T Update(T entity);
        void Delete(T entity);
    }

Это ни что иное, как реализация DAO паттерна. Сам же репозиторий может совершенно не знать о механике и деталях хранения данных (база, файлы, сервис). На маленьких проектах разницу не так сильно видно. А на больших, когда помимо самих запросов, еще необходимо прикрутить кеширование, логирование, фильтрацию по служебным полям, вдруг оказывается, что репозиторий уже совсем не то же, что DAO.
Отсюда и вопросы у новичков, типа, должен ли репозиторий иметь методы GetSomethingByUser, GetUserTickets или просто CRUD не зная про другие репозитории и типы.
А современные фреймворки еще сильнее путают разрабов, реализуя весь Data Access слой. И те, что DAO называли репозиториями начинают думать, что репозитории не нужны, и можно Linq-кодом прошить всю бизнес логику. Даже картинки у Фаулера и на MSDN способствуют тому, что репозиторий воспринимается, главным образом, как провайдер данных, т.е. абстракция над RDBMS, хотя его роль более значимая при проектировании. Возможно, я начитался DDD книжек.

Не кажется ли вам, что пора идею репозитория несколько подправить, чтобы когда один говорил другому этот термин, то оба понимали что-то одно?
Re: Про путаницу с репозиториями и DAO
От: IT Россия linq2db.com
Дата: 13.06.16 15:58
Оценка: +4
Здравствуйте, another_coder, Вы писали:

_>Не кажется ли вам, что пора идею репозитория несколько подправить, чтобы когда один говорил другому этот термин, то оба понимали что-то одно?


Нам кажется, что идею репозитория в отношении БД давно пора похоронить.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Про путаницу с репозиториями и DAO
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.06.16 16:17
Оценка:
Здравствуйте, IT, Вы писали:

IT>Нам кажется, что идею репозитория в отношении БД давно пора похоронить.


А что за класс у нас в проекте, называется Repository?
Re: Про путаницу с репозиториями и DAO
От: Sinix  
Дата: 13.06.16 17:02
Оценка: +5
Здравствуйте, another_coder, Вы писали:

_>Возможно, я начитался DDD книжек.

Если коротко, то domain-driven — это очень здравый и циничный подход к проектированию систем. Ещё раз: про проектирование, про "способ думать", не про реализацию. Т.е. как только очередной эксперт начинает рассказывать про репозитарий на уровне кода, потому что DDD, то можно доставить томик и ласково стучать по башке, предлагать освежить.


ну и далее по тексту
Автор: Sinix
Дата: 15.02.16
.

_>Не кажется ли вам, что пора идею репозитория несколько подправить, чтобы когда один говорил другому этот термин, то оба понимали что-то одно?

Угу, закопать. Как и самый страшный грех архитектора: привычку лепить паттерны без оглядки на инструменты реализации.

Начинать надо с задачи, языка и используемых фреймворков — вот тогда уже можно что-то предметно обсуждать.
Re[2]: Про путаницу с репозиториями и DAO
От: hrensgory Россия  
Дата: 13.06.16 18:54
Оценка: +1
13.06.2016 18:58, IT пишет:
> _>Не кажется ли вам, что пора идею репозитория несколько подправить,
> чтобы когда один говорил другому этот термин, то оба понимали что-то одно?
>
> Нам кажется, что идею репозитория в отношении БД давно пора похоронить.

Ура, я такой не один.

--
WBR,
Serge.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Про путаницу с репозиториями и DAO
От: IT Россия linq2db.com
Дата: 13.06.16 20:18
Оценка:
Здравствуйте, MozgC, Вы писали:

IT>>Нам кажется, что идею репозитория в отношении БД давно пора похоронить.


MC>А что за класс у нас в проекте, называется Repository?


У нас класс так называется только потому что как-то не придумалось другого названия. Но с предложенным интерфейсом репозитория он не имеет ничего общего. Во-первых, у нас вообще нет никакого интерфейса, потому что он нафиг не нужен. Во-вторых, основная задача нашего класса — возможность тестирования процессов, которые его используют без чтения данных из базы. Т.е. это ближе к DI, чем к паттерну Repository. А здесь репозиторий нужен как часть или даже замена DAO, такой классический пережиток тяжелого прошлого.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Про путаницу с репозиториями и DAO
От: Sharov Россия  
Дата: 14.06.16 11:42
Оценка:
Здравствуйте, another_coder, Вы писали:

_>Это ни что иное, как реализация DAO паттерна. Сам же репозиторий может совершенно не знать о механике и деталях хранения данных (база, файлы, сервис). На маленьких проектах разницу не так сильно видно. А на больших, когда помимо самих запросов, еще необходимо прикрутить кеширование, логирование, фильтрацию по служебным полям, вдруг оказывается, что репозиторий уже совсем не то же, что DAO.

_>Отсюда и вопросы у новичков, типа, должен ли репозиторий иметь методы GetSomethingByUser, GetUserTickets или просто CRUD не зная про другие репозитории и типы.

У меня для всех центральных типов, т.е. master в терминологии master-detail есть свой репозиторий и вот там как раз куча вот таких методов GetSomethingByUser, GetSomethingByUser и т.д.
Кодом людям нужно помогать!
Re[2]: Про путаницу с репозиториями и DAO
От: diez_p  
Дата: 15.06.16 19:41
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, another_coder, Вы писали:


_>>Не кажется ли вам, что пора идею репозитория несколько подправить, чтобы когда один говорил другому этот термин, то оба понимали что-то одно?


IT>Нам кажется, что идею репозитория в отношении БД давно пора похоронить.


А можно по подробнее(для собственного кругозора)?
По серьезному с данными из базы мы не работаем, в основном редактирование гридов, и есть чуть по сложнее функционал — ну и все.
Простой DataGrid в .NET, очень похож на репозиторий. Хранятся объекты, со статусом Updated/Deleted/Inserted и потом по некой кнопке ОК все это пишется в базу. Это тривиальный кейс, но для редактирования гридов вполне. Если усложнить логику, то что-то делаем, делаем, делаем, потом жмем Save и все ушло в базу (тут конечно можно нарваться на конфликты, но это уже другая тема).
Re: Про путаницу с репозиториями и DAO
От: Baudolino  
Дата: 16.06.16 06:09
Оценка:
Этот вопрос в сети поднимается довольно часто, но можно поговорить о нем ещё раз.
Во-первых, для репозитория есть достаточно хорошее определение: это коллекция, реализующая долгосрочное хранение однотипных объектов модели предметной области и абстрагирующая пользователя от деталей реализации (=чуть другими словами формулировка Фаулера). Приведенный вами пример полностью соответствует этому определению, поэтому вполне может описывать интерфейс репозитория.
Во-вторых, Фаулер не выделяет отдельно DAO как паттерн и, честно говоря, я не встречал классификации, в которой одновременно существуют оба паттерна, поэтому можно их считать независимыми друг от друга. Если взглянуть например на эту статью, которая описывает DAO так, как его понимают очень многие разработчики, то можно заметить, что DAO это просто компонент слоя доступа к данным, без каких-либо дополнительных определений и условий. Фактически, под определение DAO попадают все паттерны раздела Data Source Architectural Layer отсюда.
Т.е. любой репозиторий — DAO, но не любой DAO — репозиторий.

Далее, вы пишете:
a>А на больших, когда помимо самих запросов, еще необходимо прикрутить кеширование, логирование, фильтрацию по служебным полям, вдруг оказывается, что репозиторий уже совсем не то же, что DAO.
Здесь все смешано в одну большую кучу с неверным заключением. Логика реализации "запросов" (методов, или, как в олдскульном ООП, "сообщений"?), кэширование и логирование — особенности внутренней реализации, о которых клиент не знает. Фильтрация по служебным полям — часть интерфейса DAO (и, как сказано выше, может быть, репозитория) и объекта доменной модели (свойство объекта, которое использует бизнес-логика, является частью доменной модели, поэтому слово "служебный" здесь не имеет особого смысла).
Re[2]: Про путаницу с репозиториями и DAO
От: Baudolino  
Дата: 16.06.16 06:10
Оценка:
Здравствуйте, IT, Вы писали:
IT>Нам кажется, что идею репозитория в отношении БД давно пора похоронить.
Это почему же?
Re[3]: Про путаницу с репозиториями и DAO
От: IT Россия linq2db.com
Дата: 16.06.16 18:54
Оценка:
Здравствуйте, Baudolino, Вы писали:

IT>>Нам кажется, что идею репозитория в отношении БД давно пора похоронить.

B>Это почему же?

Потому что в последние лет 8 появились более продвинутые способы работы с БД.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Про путаницу с репозиториями и DAO
От: Baudolino  
Дата: 17.06.16 07:51
Оценка:
Здравствуйте, IT, Вы писали:

IT>Потому что в последние лет 8 появились более продвинутые способы работы с БД.

А можно более развернуто? Какие?
Re[2]: Про путаницу с репозиториями и DAO
От: another_coder Россия  
Дата: 17.06.16 08:18
Оценка:
Здравствуйте, Baudolino.

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

Вы писали:
B>Во-первых, для репозитория есть достаточно хорошее определение: это коллекция, реализующая долгосрочное хранение однотипных объектов модели предметной области и абстрагирующая пользователя от деталей реализации (=чуть другими словами формулировка Фаулера).
В настоящее время, такое определение, на мой взгляд, вводит в заблуждение людей, т.к. является слишком общим. За этим определением может скрываться любой функционал, абсолютно любой. И приведенный пример, действительно, удовлетворяет. Но это не репозиторий.

B>Т.е. любой репозиторий — DAO, но не любой DAO — репозиторий.

Из-за такого представления и возникает путаница в общении. Думаю, следует разделять мух от котлет: DAO — абстракция над хранилищем данным, без логики связанной с бизнесом, Repository — аналогично, как aggregate root в DDD.

Ничего не смешано. Смотрите сами и попробуйте подумать, где вы будете все это сводить в единую систему?
B>Логика реализации "запросов"
Это чистый DAO, или ORM framework.

B>кэширование и логирование — особенности внутренней реализации, о которых клиент не знает.

Это сервисная логика, которая может меняться не зависимо от хранилища по не зависящим от проектирования и ПО хотелкам либо клиента, либо самих разрабов. На каком уровне она будет использоваться?

B>Фильтрация по служебным полям — часть интерфейса DAO (и, как сказано выше, может быть, репозитория)

Служебные поля служебным полям рознь. Есть те, что являются частью бизнес логики, есть те, частью целостности хранения данных, а есть те, что нужны в рамках обслуживания системы. Куда относится, например, IsDeleted (имеется ввиду, что ничего не удаляется), а куда фильтрация по CreatedDate (имеется ввиду, не показывать слишком старые)?

И в дополнение при наличии всего-всего вы начнете думать, как же все это протестировать. Начнете выделять функциональности, чтобы от них изолироваться. Вы обнаружите, что, например, IsDeleted должен быть на уровне DAO, CreatedDate — в Repository, при этом вам 2L кеширование нужно и вы думаете о том, чтобы прицепить 3rd party библиотеку и это тоже нужно в Repsoitory. А вот аудитлог вам скорее всего понадобиться в DAO. Хотя, какую-то умную служебную (алерты для саппорта, например, или для сбора спец информации) нотификацию вы опять же засунете в репозиторй.

Конечно, условий слишком много, чтобы проводить четкую линию между между тем что куда относится. Но то, что хочется видеть, это понимание того, что Data Layer — это не один класс, в который сначала все сваливается, а потом превращается в то, что трудно тестировать и поддерживать. Это должно быть просто и сердито: DAO — объект доступа к данным, Repository — объект подготовки данных к BO. Без всяких обобщений и "перевоплощений" ропозитория в DAO, как вы писали.

И сразу отвечу на возможный вопрос о кеше и доп логике в ропозитории. Нет, она не прошивает его код, а инжектится туда, будучи описанной в других классах. И никак иначе.
Отредактировано 17.06.2016 8:30 another_coder . Предыдущая версия .
Re[3]: Про путаницу с репозиториями и DAO
От: Baudolino  
Дата: 17.06.16 09:36
Оценка:
Здравствуйте, another_coder, Вы писали:

_>Здравствуйте, Baudolino.


_>В настоящее время, такое определение, на мой взгляд, вводит в заблуждение людей, т.к. является слишком общим. За этим определением может скрываться любой функционал, абсолютно любой.

Любой, удовлетворяющий определению паттерна. Это нормальная ситуация.

_>И приведенный пример, действительно, удовлетворяет. Но это не репозиторий.

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


B>>Т.е. любой репозиторий — DAO, но не любой DAO — репозиторий.

_>Из-за такого представления и возникает путаница в общении.
Путаница в общении обычно возникает из-за того, что кто-то что-то не знает или не понимает. Обычно решается фразой "давай для начала определим, что такое..." и глоссарием в архитектурной документации.

_>Думаю, следует разделять мух от котлет: DAO — абстракция над хранилищем данным, без логики связанной с бизнесом, Repository — аналогично, как aggregate root в DDD.

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

_>Ничего не смешано. Смотрите сами и попробуйте подумать, где вы будете все это сводить в единую систему?

B>>Логика реализации "запросов"
_>Это чистый DAO, или ORM framework.
Что такое "чистый DAO"? Что значит в данном случае "или": если это ORM, то это не DAO? Или DAO=ORM? Как от этого меняется определение репозитория?

B>>кэширование и логирование — особенности внутренней реализации, о которых клиент не знает.

_>Это сервисная логика, которая может меняться не зависимо от хранилища по не зависящим от проектирования и ПО хотелкам либо клиента, либо самих разрабов. На каком уровне она будет использоваться?
Что такое "сервисная логика"? Вспомогательная? Логика сервисного слоя? Кэширование — это алгоритмический, а не архитектурный паттерн. Как реализован ваш компонент доступа к БД — это скрытая деталь реализации. Репозиторий может кэшировать, шлюз БД — может, клиент слоя доступа к данным — может. Суть определений от этого не меняется.

B>>Фильтрация по служебным полям — часть интерфейса DAO (и, как сказано выше, может быть, репозитория)

_>Служебные поля служебным полям рознь. Есть те, что являются частью бизнес логики, есть те, частью целостности хранения данных, а есть те, что нужны в рамках обслуживания системы. Куда относится, например, IsDeleted (имеется ввиду, что ничего не удаляется), а куда фильтрация по CreatedDate (имеется ввиду, не показывать слишком старые)?
Это специфика функциональных требований к конкретной системе, которые нужно как следует анализировать. Давайте разберем на примере IsDeleted. Само по себе такое поле никогда не появляется — оно является частью требований к инфраструктуре приложения, к тому как обрабатываются данные вообще, а не конкретные сущности. Как правило, его задача — сохранить данные для аудита, планового или в чрезвычайной ситуации (для бэкапа такой способ подходит плохо). Для того, чтобы понять, на каком уровне этот флаг появляется, необходимо найти конечного пользователя и используемый им интерфейс. Если это то же самое приложение, то без вариантов — это часть доменной модели и интерфейс DAO знает о его существовании (например, в виде специальных методов типа findDeleted). Если для чтения этого флага используется другое приложение (например, штатный клиент БД) — у вас имеет место быть интеграция через БД, этот флаг является частью протокола интеграции, т.е. особенностью внутренней реализации DAO. При этом все вышесказанное никак не влияет на выбор конкретного вида DAO: это может относиться в равной степени к репозиторию, шлюзу таблицы БД (table data gateway) и т.п.

_>И в дополнение при наличии всего-всего вы начнете думать, как же все это протестировать. Начнете выделять функциональности, чтобы от них изолироваться. Вы обнаружите, что, например, IsDeleted должен быть на уровне DAO, CreatedDate — в Repository, при этом вам 2L кеширование нужно и вы думаете о том, чтобы прицепить 3rd party библиотеку и это тоже нужно в Repsoitory. А вот аудитлог вам скорее всего понадобиться в DAO. Хотя, какую-то умную служебную (алерты для саппорта, например, или для сбора спец информации) нотификацию вы опять же засунете в репозиторй.

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

_>Конечно, условий слишком много, чтобы проводить четкую линию между между тем что куда относится. Но то, что хочется видеть, это понимание того, что Data Layer — это не один класс, в который сначала все сваливается, а потом превращается в то, что трудно тестировать и поддерживать.


_>Это должно быть просто и сердито: DAO — объект доступа к данным, Repository — объект подготовки данных к BO. Без всяких обобщений и "перевоплощений" ропозитория в DAO, как вы писали.

Кому должно? Вот тут я, кстати, начал примерно понимать, куда вы клоните. Давайте отбросим на минутку все наши представления о паттернах-фигаттернах, и рассмотрим задачу в общем виде, чтобы определить их заново.
Итак, у нас есть бизнес-логика, реализованная в рамках ООП. Есть хранилище данных, чаще всего реляционное (РСУБД). Нам нужно обеспечить передачу данных из хранилища в бизнес-логику. Поскольку хранилище тяжелое, реализованное посторонними людьми, мы хотим в целях простоты поддержки и тестирования изолировать доступ к нему в отдельном архитектурном слое. Назовем его Data Access Layer (DAL). В этом слое у нас будет некоторое количество компонентов, которые будет использовать бизнес-логика. Следующим шагом мы определим вид этих компонентов, выбрав уровень связности бизнес-логики и хранилища. Если мы готовы пожертвовать гибкостью в пользу большей производительности, мы выбираем интерфейс компонентов, в котором каждый метод представляет собой некий запрос к БД и возвращает временный объект (DTO). Мы называем тип таких компонентов Table Data Gateway. Если мы хотим наоборот, чтобы бизнес-логика воспринимала хранилище просто как некую коллекцию, мы в интерфейсе компонентов DAL будем использовать методы вида добавить/заменить/удалить и назовем такие компоненты Repository. Каждый такой компонент будет соответствовать одной сущности модели (или одной иерархии). Определившись с интерфейсами, приступаем к выбору реализации. Мы будем использовать какое-либо стандартное API для доступа к БД, которое позволит нам выполнять SQL-запросы и получать в ответ табличные данные.
Поскольку нам нужно преобразовать реляционную модель в объектную, нам требуется объектно-реляционное отображение (ORM). Его можно реализовать самостоятельно, строя запросы и преобразуя полученные данные (в таком случае стоит вынести логику построения запросов и чтения результатов в отдельный класс — Object-Relational Mapper), а можно выбрать готовое ORM-решение, которое используя декларативную модель описания отображения, сведет код вашего репозитория к одной строчке в каждом методе.
Далее, хранилище далеко от узла развертывания, поэтому мы хотим ускорить его работу за счет алгоритма кэширования. Мы можем использовать готовый кэш, поэтому добавим в нужные методы компонента DAL попытку чтения из кэша перед чтением из БД. Кэш будет представлен у нас простым интерфейсом с методами вида get/putIfAbsent/invalidate и т.п. За инжектирование конкретной реализации кэша в наш компонент DAL ,будет отвечать контейнер DI. Но лучше всего будет в таком случае настроить кэш в ORM/f и вообще не заморачиваться на собственную реализацию логики. Что касается журналирования и обработки ошибок, замусоривать код такой вспомогательной логикой не обязательно, если у вас есть возможность завернуть ваши компоненты в прокси, которые будут журналировать вызовы методов. Это обычно делается с помощью AOP. А теперь внимание, вопрос: а где здесь собственно должно появиться ваше разделение на "объект доступа к данным" и "объект подготовки данных к ВО"? (и что такое ВО?)


_>И сразу отвечу на возможный вопрос о кеше и доп логике в ропозитории.

А кто бы ставил этот вопрос? Вроде все нормальные люди давно уже используют DI.
Re[4]: Про путаницу с репозиториями и DAO
От: Qulac Россия  
Дата: 17.06.16 10:03
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Baudolino, Вы писали:


IT>>>Нам кажется, что идею репозитория в отношении БД давно пора похоронить.

B>>Это почему же?

IT>Потому что в последние лет 8 появились более продвинутые способы работы с БД.


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

 class UserCollection
 {
   int Add(User user){}

   void Remove(User user){}

   IEnumerable<User> Find(Specification s){}
 }


Чем не репозиторий? Если при разработке использовать принципы grasp, то репозиторий должен был бы появиться.
Программа – это мысли спрессованные в код
Re[5]: Про путаницу с репозиториями и DAO
От: Sinix  
Дата: 17.06.16 10:25
Оценка:
Здравствуйте, Qulac, Вы писали:


Q>Чем не репозиторий? Если при разработке использовать принципы grasp, то репозиторий должен был бы появиться.


Кэп: код здорового человека выглядит примерно так:
[Transactional]
void SetRecordData(string code, string data)
{
  var existing = Context.FirstOrDefault<MyRecord>(r => r.Code == code);
  if (data == null)
  {
    existing?.Delete();
  }
  else
  {
    if (existing == null)
    {
       existing = Context.NewObject<MyRecord>(r => r.Code = code);
    }

    existing.Data = data;
  }  
}


Т.е. ноль технических деталей, вся магия под капотом.

Разумеется, код сферический в вакууме, просто чтоб показать основные сценарии. В отдельных случаях может оказаться выгоднее сгенерить sql merge statement, в других — заморочиться с корректной обработкой одновременных update/delete и тыды и тыпы.
Re[5]: Про путаницу с репозиториями и DAO
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.06.16 10:34
Оценка: +1
Здравствуйте, Qulac, Вы писали:

IT>>Потому что в последние лет 8 появились более продвинутые способы работы с БД.

Q>А причем тут БД, а если нужно хранить данные просто в памяти, а для хранения скидывать их в файл через серелизацию, как тогда организовывать работу с данными?
При том, что без БД репозиторий имеет еще меньше смысла.

Если у вас тупо коллекция в памяти, то это List<T>. На крайняк Dictionary<TKey, T>. В нужные моменты времени они сериализуются в файл, а при запуске программы десериализуются из файла.
Re[6]: Про путаницу с репозиториями и DAO
От: Qulac Россия  
Дата: 17.06.16 10:47
Оценка: +1 -1
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Qulac, Вы писали:


IT>>>Потому что в последние лет 8 появились более продвинутые способы работы с БД.

Q>>А причем тут БД, а если нужно хранить данные просто в памяти, а для хранения скидывать их в файл через серелизацию, как тогда организовывать работу с данными?
G>При том, что без БД репозиторий имеет еще меньше смысла.

G>Если у вас тупо коллекция в памяти, то это List<T>. На крайняк Dictionary<TKey, T>. В нужные моменты времени они сериализуются в файл, а при запуске программы десериализуются из файла.


Не ну это естественно, что внутри нашей коллекции будет List, Dictionary или что то еще подобное. Смысл: у нас ни чего не торчит лишнего через интерфейс, а если какие-то выборки данных повторяются в программе в многих местах, то здесь мы их объедением в нашей коллекции в виде методов. Вся логика работы с данными в одном месте, проще тестировать.
Программа – это мысли спрессованные в код
Re[6]: Про путаницу с репозиториями и DAO
От: Qulac Россия  
Дата: 17.06.16 10:49
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Qulac, Вы писали:



Q>>Чем не репозиторий? Если при разработке использовать принципы grasp, то репозиторий должен был бы появиться.


S>Кэп: код здорового человека выглядит примерно так:

S>
S>[Transactional]
S>void SetRecordData(string code, string data)
S>{
S>  var existing = Context.FirstOrDefault<MyRecord>(r => r.Code == code);
S>  if (data == null)
S>  {
S>    existing?.Delete();
S>  }
S>  else
S>  {
S>    if (existing == null)
S>    {
S>       existing = Context.NewObject<MyRecord>(r => r.Code = code);
S>    }

S>    existing.Data = data;
S>  }  
S>}
S>


S>Т.е. ноль технических деталей, вся магия под капотом.


S>Разумеется, код сферический в вакууме, просто чтоб показать основные сценарии. В отдельных случаях может оказаться выгоднее сгенерить sql merge statement, в других — заморочиться с корректной обработкой одновременных update/delete и тыды и тыпы.


Ну на здоровье как говориться, кому как нравиться.
Программа – это мысли спрессованные в код
Re[7]: Про путаницу с репозиториями и DAO
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.06.16 11:45
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Qulac, Вы писали:


IT>>>>Потому что в последние лет 8 появились более продвинутые способы работы с БД.

Q>>>А причем тут БД, а если нужно хранить данные просто в памяти, а для хранения скидывать их в файл через серелизацию, как тогда организовывать работу с данными?
G>>При том, что без БД репозиторий имеет еще меньше смысла.

G>>Если у вас тупо коллекция в памяти, то это List<T>. На крайняк Dictionary<TKey, T>. В нужные моменты времени они сериализуются в файл, а при запуске программы десериализуются из файла.


Q>Не ну это естественно, что внутри нашей коллекции будет List, Dictionary или что то еще подобное. Смысл: у нас ни чего не торчит лишнего через интерфейс, а если какие-то выборки данных повторяются в программе в многих местах, то здесь мы их объедением в нашей коллекции в виде методов. Вся логика работы с данными в одном месте, проще тестировать.


В List<T> есть лишнее? Логика в разных местах? Вы о чем вообще?
Если вам в программе нужен список людей, например, то зачем городить что-то поверх List<T>?

Вам не надо тестировать List<T>. А если выборки повторяются, то делаете extension-метод для List<Person>.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.