В статье Проблемный шаблон Repository и судя по комментариям многим не понравилась та часть, где объекты *Query скрываются за IQueryFactory. С первого взгляда кажется, что QueryFactory превращается в очередной god-object.
Я уже отвечал, что это не так, потому что в самой QueryFactory нет логики и она только создает объекты запросы. Теперь я могу дать ссылки на две статьи, где от QueryFactory остался только интерфейс, который реализуется с помощью IoC.
Первая статья моего коллеги Тимура Рахматиллаева совсем недавно выложена на Хабре Получение экземпляра класса запроса по сигнатуре его интерфейса.
Вторая статья моего бывшего коллеги Дмитрия Крючкова была выложена в его блоге Alternative to repository pattern: query objects using Castle Windsor с примеры кода на GitHub'е
Советую изучить обе статьи, довольно интересные подходы. С первого взгляда могут показаться слишком сложными и абстрактными, но если их попробовать, то преимущества становятся очевидны.
Преимущества всегда очевидны. Дьявол прячется в недостатках.
ОтветитьУдалитьАлександр, можно вопрос именно к тебе, как к пустившему волну? Ты же придерживаешься принципа SRP при проектировании? Можешь сформулировать responsibility класса LoginCriterion в примере Тимура?
А мне вообще непонятен ажиотаж вокруг этого ServiceLocator-подобного IQueryFactory. Насколько я понимаю, вещь сугубо опциональная. Предпочитаешь явно объявлять зависимости - прокидывай Query напрямую, не любишь прокидывать много зависимостей - прокидывай IQueryFactory, хотя это 1. практически прокидывание IoC контейнера 2. сделает стаббинг/мокинг зависимостей менее интуитивным
ОтветитьУдалитьВ любом случае, IQueryFactory никак не влияет на достоинства/недостатки Query - он является надстройкой (пусть, на мой взгляд, и сомнительной) над ним.
@Pasha
ОтветитьУдалитьЭто можно сказать контекст запроса, а фактически DTO для передачи критериев запроса.
@Idsa
ОтветитьУдалитьЕще есть один нюанс - уменьшается количество кода. Опять же на любителя.
Александр, ты о каком коде? О тех трех строчках на каждую зависимость:
ОтветитьУдалитьprivat readonly IQuery1 _query1;
public SomeType(IQuery1 query1)
{
_query1 = query1;
}
Да, неприятный момент. Меня напрягает, когда прокидывание зависимостей - портянка на полэкрана. Кажется, Мартин писал, что если больше 3-4 зависимостей, то это уже говнокод, и его нужно рефакторить. Но рефактиронг в сторону IQueryFactory - еще больший говнокод (пусть и удобный). Хм...
@Idsa
ОтветитьУдалитьЭто откуда?
@Александр
ОтветитьУдалитьЧто именно?
@Idsa
ОтветитьУдалитьВот это откуда:
> О тех трех строчках на каждую зависимость:
privat readonly IQuery1 _query1;
public SomeType(IQuery1 query1)
{
_query1 = query1;
}
@Александр
ОтветитьУдалитьЭто просто пример пробрасывания непосредственно Query, а не QueryFactory
@Idsa
ОтветитьУдалитьТак не получится, потому что IQuery* будет очень много.
@Александр
ОтветитьУдалитьИх будет столько же, сколько и методов в IQueryFactory.
@Idsa
ОтветитьУдалитьВ ссылках, которые я привел у IQueryFactory есть только один метод не зависимо от кол-ва объектов Query*
Ну ок. Если отталкиваться от статей, то будет прокидываться не IQuery1, а IQuery<SomeCriterion, SomeResult>.
ОтветитьУдалить@Idsa
ОтветитьУдалитьЯ не понимаю куда это будет прокидываться :)
Контроллеры, например, будут принимать только IQueryFactory, как и все остальные объекты в системе.
@Александр
ОтветитьУдалитьТак я рассматриваю ситуацию, когда QueryFactory нет
@Idsa
ОтветитьУдалитьА, когда ее нет слишком много инжектировать придется. Для однотипных объектов всё-таки надо использовать фабрику.
@Александр
ОтветитьУдалитьВ общем случае ты, наверное, прав. Но так ли много Query будет в одном сервисе/контроллере? 2, 3, 5? Насколько для нас важно явно видеть, от каких запросов зависит сервис (тестировать такие классы все же удобнее)? От ответов на эти вопросы, думаю, зависело бы мое решение, если бы я вдруг собрался переползти с IQueryable+Specifications на Queries.
@Idsa
ОтветитьУдалитьДопустим в начала их будет по 3-4 в каждом контроллере, а потом по 10-12. Будешь рефакторить?
Очевидно же, что кол-во запросов увеличивается с ростом проекта.
>>Будешь рефакторить?
ОтветитьУдалитьСкорее всего, да
>>Очевидно же, что кол-во запросов увеличивается с ростом проекта.
Количество запросов в целом - да, увеличивается. Количество запросов в конкретном сервисе/контроллере - не факт. По крайней мере их увеличение (как и любых других зависимостей) - отличной повод задуматься о рефакторинге.
@Idsa
ОтветитьУдалитьЯ за фабрику с самого начала :)
@Александр
ОтветитьУдалитьПожалуй, ты меня убедил :)