• А можете поревьювить?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Глаза радуются, когда такой код видишь, не надо спрашивать - где он тот кто писал

    Немного косметики:
    1. Константы можно определять в интерфейсах, это здорово помогает, незачем для них целая папка с классами

    2. Билдер предполагает (на мой взгляд) строительство чего-то сложного в такой нотации
    ->where()->where()->group(). Если нечто просто возвращает другой объект, это может быть фабрикой. Я имею в виду даже называться фабрика. Билдер означает "здесь столько параметров, что их в одном месте тупо не проставить, и нужно отсюда взять один, отсюда другой, соединить хитро" и тд. поэтому он билдер.

    3. Есть там место где тебе очень нравится if ($a instanceof Class) и раз 20. Можешь закинуть имена классов в качестве ключей в массив и тупо чекать isset(). Разве что ты планируешь наследоваться, тогда isset() будет не очень. Но в любом случае форич упростит этот код строк на 30

    4. по эксепшенам как бы не превратилось в холивар, но смело бросай стандартные Пхпшные эксепшены с небольшой ремарочкой - оберни их в свой неймспейс (в этом случае категории останутся стандартные, а твой модуль будет бросать как бы "свои собственные"). Для случаев когда тебе очень нужно что-то логировать и вытягивать из эксепшена, я бы предусмотрел как и у тебя ClientException только вместо Response просто пхал бы туда ...$arguments. Что кинешь - то и достанешь потом. То есть стандартные мессаг, код и предыдущий будет как у всех эксепшенов - а аргументы - чтобы их логировать. Не думаю что очень ты выиграл от того, что сделал эксепшен в котором первым параметром обязательно респонс. Теперь он может быть использован только здесь и нигде больше. Если эксепшен приводит к каким-то действиям кроме "поймать", "перебросить", "уведомить" или "залогировать" - очень вероятно что это не эксепшен. Хотя такой вариант может быть почему нет.

    5. Интерфейсы лежат вместе с классами это не плохо, но рядом с интерфейсом нет такого же класса, а идут другие, реализующие интерфейс. Похоже на абстракцию, которая могла бы быть. ActionInterface.php, Action.php и папка Action где уже лежат Actions. Но это тоже косметика. В самих экшенах я бы все таки добавил слово Action несмотря на то что неймспейс тоже Action. Если открыть много файлов в редакторе, то сверху одинаковые имена могут дублиться, а так видно - что тут речь про экшен, а там не про экшен.

    6. Вот что мне показалось странным - у тебя куча "экшенов" подразумевающих что это "действие". Но там внутри лежат сущности названные "Действие". Ну то есть ты создал много классов задача которых входные аргументы проверить по типу (кинуть InvalidArgumentException если косяк, по сути), и больше ничего. Ну у них есть геттеры и свойства. Это состояние никак не меняется, оно просто устанавливается и валидируется. Можно. Выглядит красиво, аккуратно. Но бегает у меня сзади призрак который намекает что зарраза, столько файлов создал, он не задолбался? Впрочем если апишка бота непредсказуема - типа на одно возвращает одно, на второе другое и нет ничего общего - то такой способ валидации приемлем. К сожалению кроме разработчика который будет на базе этой штуки лепить, никто не сможет на них никак среагировать, т.к. InvalidArgumentException это в первую очередь "уведомить разработчика что сюда попало то, что не должно", отловить и перевести на несколько языков такую ошибку не получится. Собственно поэтому прибегают к валидации там, где этой штукой будет пользоваться менее опытный разработчик или пользователь.

    Наверное всё, можно пообщаться в той же телеге, если интересно детальнее. В целом понравилось
    Ответ написан
    2 комментария
  • Как писать кошерные юнит тесты в symfony2 когда вся логика в контроллерах?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    юнит тесты - это тесты которые тестируют юниты (то есть подразумевается хоть какая-то степень изоляции, от полной (когда все замокано) до не очень полной (если мокать все не сильно удобно)).

    В случае с логикой контроллеров у вас инфраструктура и бизнес логика связаны сильно, потому ваш путь - функциональные и интеграционные тесты. (ибо на данном этапе вынести все в сервисы и изолировать не особо то получится за разумное время).

    По вашим пунктам - делайте так, как вам удобно. Ну то есть суть всего сводится к тому что бы с кодом вашего приложения было удобно работать. Тесты это способ упрощения внесения изменений в код. Если вам из-за тестов не удобно - надо придумать как сделать так что бы было удобно (либо у вас что-то не так с тестами либо с кодом, раз его не удобно тестить).
    Ответ написан
    2 комментария
  • Как сделать midleware в django, который меняет TEMPLATE_DIRS?

    @marazmiki
    Укротитель питонов
    Когда Вы делаете такие штуки, нужно иметь в виду, что объект settings глобален. Вот зайдёте Вы с мобильной версии, миддльварь сменит TEMPLATE_DIRS. А сразу же следом за Вами (пока джанга не успела начать рендерить шаблон) — кто-нибудь с компьютера. И значение TEMPLATE_DIRS вернётся в исходное.

    Ключевое слово для поиска решения — thread locals.
    Ответ написан
    9 комментариев