Search
Write a publication
Pull to refresh

Comments 7

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

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

У меня, как правило, сначала всё просто (get, add), потом код обрастает вот этими getByThisAndThat(…) , а уже потом и об архитектуре приходится думать, иначе всё превратится в месиво.

Прикольно, не знал что это прям паттерн. У нас в java в Spring Data JPA (самая популярная надстройка над ORM), функциональный интерфейс, который вызывается при формировании предиката, и имеющий and, or - так и называется: Specification.

А что за первоисточник? Черная книга по паттернам корпоративных приложений Фаулера?

Пиздец, статья то про интерфейсы а тут зачем то заумное "спецификация", даже не "контракт"

Спецификация ёб ж !

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

Задачу, похожую на вашу, я на своем проекте решал несколько иным способом:

interface QueryFilter 
{
    /**
     * Применяет условия фильтрации к переданному объекту запроса.
     */
    public function applyTo(Query &$query);
}

class DoctrineLoyaltyCardRepository extends DoctrineRepository implements LoyaltyCardRepositoryInterface
{
   // ...
    
    private function findAllByFilter(QueryFilter $filter): LoyaltyCardCollection
    {
        // Применяем базовые параметры фильтрации
        $query = $this->cardRepository->createQueryBuilder('c')
            ->andWhere('c.programId = :programId')
            ->andWhere('c.levelId = :levelId')
            ->andWhere('c.profileFilled = :profileFilled')
            ->getQuery();
        // Применяем фильтр с дополнительными параметрами
        $filter->applyTo($query);
      
        $cards = $query->getResult();
        
        return new LoyaltyCardCollection(...$cards);
    }
}

Я решал проблему созданием SearchCriteria, которая сама добавляет условия в QueryBuilder.

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

Sign up to leave a comment.

Articles