С какой целью разрабатывается фреймворк

Не относящиеся к фреймворку и программированию вопросы
Аватара пользователя
ElisDN
Сообщения: 5318
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: С какой целью разрабатывается фреймворк

Сообщение ElisDN » 2019.05.30, 13:58

BrusSENS писал(а):
2019.05.30, 02:03
Меньше классов не означает, что это хорошо. "Жирный" экшен и "тонкий" контроллер будет всё таки лучше, чем "Жирный" контроллер, уж по крайней мере в плане гибкости и самостоятельности.
В терминах путаетесь. Что метод в классе XxxController, что ваш класс XxxAction, что анонимка function ($request) отдельно - по глобальной терминологии это всё "контроллер". А "жирный" или "тонкий" - это про корректность его реализации по ответственностям.
BrusSENS писал(а):
2019.05.30, 02:03
Я же говорю, логгер - это прикладная штука и высокоуровневой она быть не может. Он только и делает, что принятую строку пишет куда-то. Если он этого не делает, но его объект существует, то тут мы просто тратим ресурсы в пустую. + можно написать свой обработчик исключений и варнингов, для продакшна вполне хватит. И приложение об этом логгере не знает, как и должно. И при чём тут UI что-то не понял. Зачем логи в UI выводить?..

Повторюсь ещё раз о том, что можно собственный обработчик исключений сделать, это дело нескольких минут. И да, через композер такой обработчик подключу в проект и при необходимости смогу полностью выпилить.
Да, для API можно освободить контроллер от рутины:

Код: Выделить всё

class Api\TaskController
{
    public function start(Task $task, Request $request, Start\Handler $handler): Response
    {
        $command = new Start\Command($task->getId());
        $handler->handle($command);
        return $this->json([]);
    }
}
И для отлова доменных сообщений сделать внешний какой-нибудь глобальный обработчик, логирующий исключение и возвращающий красивый ответ:

Код: Выделить всё

class DomainExceptionHandlerMiddleware
{
    public function __invoke(Request $request,  callable $next): Response
    {
        try {
            return $next($request);
        } catch (DomainException $e) {
            $this->errorHandler->handle($e);
            return $this->json(['error', $e->getMessage()], 400);
        }
    }
}
Но всё меняется, когда приходит HTML UI. Там уже надо сообщение прямо в контроллере поймать и красиво во flash на этой же странице над формой вывести:

Код: Выделить всё

class Api\TaskController
{
    public function assign(Task $task, Request $request, Executor\Assign\Handler $handler): Response
    {
        $command = new Executor\Assign\Command($task->getId());
        $form = $this->createForm(Executor\Assign\Form::class, $command);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            try {
                $handler->handle($command);
                $this->addFlash('success', 'Member is successfully assigned.');
                return $this->redirectToRoute('tasks.show', ['id' => $task->getId()]);
            } catch (DomainException $e) {
                $this->errorHandler->handle($e);
                $this->addFlash('error', $e->getMessage());
            }
        }

        return $this->render('tasks/assign.html.twig', [
            'task' => $task,
            'form' => $form->createView(),
        ]);
    }
}
Здесь уже внешние Middleware не помогут, так как мы сами ошибку ловим и через throw $e дальше не кидаем. Поэтому сами её и должны в ErrorHandler для логирования закинуть. Так и возникает необходимость тянуть логирование в контроллер.
BrusSENS писал(а):
2019.05.30, 02:03
Ну вот, говорим про то, что бы всё автоматически было, а в итоге руками выпиливаем хардкод зависимости, за что и ругали Yii)
Немного за другой хардкод зависимости ругали.
BrusSENS писал(а):
2019.05.30, 02:03
Создатели PHP дали нам возможность работы с исключениями (и далеко неплохую кстати), а у нас пользуются ей для реализации валидаторов в каноничном DDD. Смех да и только.
Создателии всех языков как раз и придумали исключения для работы с исключительными ситуациями. А в PHP ими пользоваться по назначению до сих пор не научились и сам язык с ними до сих пор не очень подружили, оставив мультипарадигменным.
BrusSENS писал(а):
2019.05.30, 02:03
Только и читаешь, как в PHP придумали как мылом гвозди забивать. Не хочу никого обидеть, но стали уже просто с ума сходит с принципами каноничной архитектуры. А в итоге видал, как один клоун делал классы для того, что бы текстовые константы имели тип. Он об SPL даже не знает, зато о DDD пишет (если найду ссыль на эту статью, обязательно скину).
Увы, но нет у PHP конструкций для структур данных и перечислений. Вот многие гвозди и приходится как-то мылом забивать.
BrusSENS писал(а):
2019.05.30, 02:03
В случае Yii, данный прикладной сервис относится к действию, нежели к контроллеру. Зачем тащить в контроллер зависимость, которая нужна для 1 действия из всех? Для этого, в реалиях Yii2 подходят прекрасно StandAlone экшены. Свой конструктор, никакого лишего кода логики из других действий, свои методы, которые доступны только для данного действия.
Да, я в курсе, что в Yii не ничего из мной перечисленного. Я вообще говорю о разных вариантах.
BrusSENS писал(а):
2019.05.30, 02:03
Тут конечно стоит добавить, что я очень надеюсь, что в Yii когда-нибудь выпилят экшены и контроллер будет обрабатывать реально одну команду, а не будет служить своего рода списком действий.
Это было бы и сейчас реально делать контроллер с одним экшеном, если бы маршрутизация от этого не страдала.

Аватара пользователя
BrusSENS
Сообщения: 530
Зарегистрирован: 2012.07.26, 06:51
Откуда: Новороссийск
Контактная информация:

Re: С какой целью разрабатывается фреймворк

Сообщение BrusSENS » 2019.05.31, 01:16

ElisDN писал(а):
2019.05.30, 13:58
В терминах путаетесь. Что метод в классе XxxController, что ваш класс XxxAction, что анонимка function ($request) отдельно - по глобальной терминологии это всё "контроллер". А "жирный" или "тонкий" - это про корректность его реализации по ответственностям.
Не, не путаюсь. У меня просто привычка на тематических форумах говорить в контексте. Тут Yii и я про контекст Yii. И, полагаю правильнее будет не анонимка, а объект всё таки, в контексте опять таки Yii) Просто реализация контроллер в других фреймворках +-, но всё таки отличается. Тем не менее, для Yii вариант со StandAlone экшенами я проверял на практике и понимаю о чём говорю. Для Yii, что бы не было много каши в контроллере - экшены отдельными классами, всегда ведь проще найти файл и смотреть только реализацию в одном файле, нежели по тысячи строк бегать и искать что у тебя и где, + когда специфичные для 1 действия методы закиданы в 1 класс - не самое приятное потом в них что-то менять при необходимости. Если когда-нибудь смотрели код C++ средненького приложения, то думаю Вам знакома ситуация, когда 100500 классов в 1 файле написаны и там же из них создаются объекты) Поэтому чем меньше файл, тем приятнее с ним потом работать.
ElisDN писал(а):
2019.05.30, 13:58

Да, для API можно освободить контроллер от рутины:

Код: Выделить всё

class Api\TaskController
{
    public function start(Task $task, Request $request, Start\Handler $handler): Response
    {
        $command = new Start\Command($task->getId());
        $handler->handle($command);
        return $this->json([]);
    }
}
И для отлова доменных сообщений сделать внешний какой-нибудь глобальный обработчик, логирующий исключение и возвращающий красивый ответ:

Код: Выделить всё

class DomainExceptionHandlerMiddleware
{
    public function __invoke(Request $request,  callable $next): Response
    {
        try {
            return $next($request);
        } catch (DomainException $e) {
            $this->errorHandler->handle($e);
            return $this->json(['error', $e->getMessage()], 400);
        }
    }
}
Но всё меняется, когда приходит HTML UI. Там уже надо сообщение прямо в контроллере поймать и красиво во flash на этой же странице над формой вывести:

Код: Выделить всё

class Api\TaskController
{
    public function assign(Task $task, Request $request, Executor\Assign\Handler $handler): Response
    {
        $command = new Executor\Assign\Command($task->getId());
        $form = $this->createForm(Executor\Assign\Form::class, $command);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            try {
                $handler->handle($command);
                $this->addFlash('success', 'Member is successfully assigned.');
                return $this->redirectToRoute('tasks.show', ['id' => $task->getId()]);
            } catch (DomainException $e) {
                $this->errorHandler->handle($e);
                $this->addFlash('error', $e->getMessage());
            }
        }

        return $this->render('tasks/assign.html.twig', [
            'task' => $task,
            'form' => $form->createView(),
        ]);
    }
}
Здесь уже внешние Middleware не помогут, так как мы сами ошибку ловим и через throw $e дальше не кидаем. Поэтому сами её и должны в ErrorHandler для логирования закинуть. Так и возникает необходимость тянуть логирование в контроллер.
На самом деле я вот какого мнения придерживаюсь. Вот все говорят о том, что глобальные переменные зло. Согласен, но всё таки чем плох тот же синглтон с Application? Почему бы не вызывать сессиию там, где её реально можно вызвать и закинуть в том же обработчике ошибок флешку? В PHP грань разума между красивым и переусложнённым ради красоты можно потерять быстро. И где можно сделать просто - нужно делать просто. Почему бы не смотреть на приложение, как на набор компонентов, а не как на монолит? Есть отдельно живущий ThrownHandler, который вообще не знает ничего, что там может быть снаружи, он сам в себе. Есть ошибка? Если нужно пишем в сессию флешку и выплёвываем. Он ничего не знает, но логи писать умеет по исключениям (что само по себе разумно). И наше приложение даже не знает, следить что-то за возникшими проблемами или нет.
ElisDN писал(а):
2019.05.30, 13:58

Немного за другой хардкод зависимости ругали.
Ну давайте только не будем с этого уже спор открывать) За хардкод ругали? Ругали) А какой это хардкод уже не важно) Хардкод он и в Африке хардкод) Хотя в случае с Yii согласен что хардкод другой, там в угоду производительности писался код и осуждать за это будет как минимум некорректно ни с Вашей, ни с моей стороны, ни со стороны ТС.
ElisDN писал(а):
2019.05.30, 13:58

Создателии всех языков как раз и придумали исключения для работы с исключительными ситуациями. А в PHP ими пользоваться по назначению до сих пор не научились и сам язык с ними до сих пор не очень подружили, оставив мультипарадигменным.
Да ладно Вам) Достойная реализация исключений, лично мне нравится) Отличий с теми же крестами совершенно не вижу, просто и ожидаемо работают, как и должно быть. А мультипарадигменность - это ведь не плохо) PHP как и другой язык развивается, синтаксис меняется в лучшую сторону. Посмотрите на кресты 11 и на 17) Будто разный яп)
В последнее время понимаю, что большая часть парадигм просто от лукавого. Брать из этих парадигм некоторые вещи бузесловно нужно, но опять же, без фанатизма, понимая что и зачем, а не из разряда "запилю-ка я бложег на DDD") Это примерно, как на крестах задумать писать тот же блог) Вроде и поко с бустом есть для того, что бы всём было с преферансом и барышнями, но зачем это делать, когда есть PHP и NGINX на которых это можно сделать гораздо быстрее и ИМХО красивее)
(Да да, PHP считаю эталоном красоты кода, не то что всякие пистоны и го, но понимаю что это связано с тем, что первый моя яп, так что помидорами не кидайтесь))
ElisDN писал(а):
2019.05.30, 13:58

Увы, но нет у PHP конструкций для структур данных и перечислений. Вот многие гвозди и приходится как-то мылом забивать.
Ну почему же?) Для некоторых вещей есть решения) Как и для той ситуации приведённой мной) И вместо того, что бы плодить интерфейс с кучей классов с одной константой в каждом классе, можно было просто запилить SPL ENUM класс. Понимаю, что не кресты далеко, но типизация есть, что и нужно было в принципе. Вроде и мыло, но уже и не совсем мыло.
И в массив собирает все константы сам одним методом, сказка же)
ElisDN писал(а):
2019.05.30, 13:58

Это было бы и сейчас реально делать контроллер с одним экшеном, если бы маршрутизация от этого не страдала.
Но всё таки, контроллер с 1 экшеном несколько не то) Вот контроллер, как action - да, тема интересная, но увы не в концепции Yii.
Native Web - небольшой блог о веб разработке (временно на ремонте)
Режим обслуживания сайта для Yii 2.x.x

Ответить